#php #mysql #sql #join #left-join
#php #MySQL #sql #Присоединиться #левое соединение
Вопрос:
Мне нужна небольшая помощь в отношении приведенного ниже запроса. Запрос работает нормально, но с небольшой логической ошибкой. Я потратил 4 часа, чтобы решить это самостоятельно, но безуспешно.
ВЫБЕРИТЕ family_id, fees_term_id, fees_head_id, fees_head_name, full_name, fees_amount, оплачено ИЗ ( ВЫБЕРИТЕ st.family_id, st.fees_head_id, st.fees_term_id, fh.fees_head_name, ft.full_name, СУММА (st.fees_amount) КАК fees_amount, СУММА (fp.paid) КАК оплаченная ИЗ fees_students_setup st СЛЕВА ПРИСОЕДИНИТЬСЯ К fees_head fh НА fh.fees_head_id = st.fees_head_id СЛЕВА ПРИСОЕДИНИТЬСЯ К fees_term ft НА ft.fees_term_id = st.fees_term_id ПЛАТА ЗА ЛЕВОЕ СОЕДИНЕНИЕ оплачивается fp ДЛЯ fp.fees_head_id = st.fees_head_id И fp.fees_term_id = st.fees_term_id И st.family_id = fp.family_id И fp.academic_start = st.academic_start И fp.academic_end = st.academic_end ГДЕ st.family_id = '316' И st.academic_start = '2013-04-01' И st.academic_end = '2014-03-31' И st.fees_term_id МЕЖДУ '1' И '1' ГРУППИРУЙТЕ ПО st.fees_head_id, st.fees_term_id ПОРЯДОК ПО st.fees_term_id ) st ;
Этот запрос выдает вывод ниже. Проблема с платным столбцом. У меня есть две таблицы (fees_setup) amp; (fees_paid). В моей таблице (fees_setup) есть две записи о вступительных взносах для двух семейных студентов. Когда оператор заплатил половину сборов. это удваивает запись. В моей таблице (fees_paid) есть одна запись, существует вступительный взнос = 1500. Но на выходе он удваивается, как вы можете видеть выше в выводе. Я знаю, почему эта проблема связана с оператором group. Пожалуйста, просмотрите мой запрос и, пожалуйста, дайте мне знать, есть ли шанс суммировать столбец fees_paid один раз. Должен ли я использовать подзапрос для этой цели? Любая идея, пожалуйста…
Комментарии:
1. Вы группируете по двум столбцам,
st.fees_head_id, st.fees_term_id
.fees_head_id
имеет два значения для этого сценария, поэтому у вас есть две строки. Возможно, вы хотите сгруппировать поfamily_id, fees_term_id
, но это трудно угадать, не зная систему более подробно.2. Привет, Эндрю, спасибо за ответ. Нет необходимости группировать по family_id, потому что я хочу показать список fees_head_name. Это я не могу использовать family. в противном случае он возвращает единственную запись. то же самое относится и к fees_term_id. Любое другое решение, которое просто суммирует столбец fees_paid без повторения fees_head_id?
3. Какой ожидаемый результат вы хотите увидеть?
4. Потребуется немного больше деталей (например, тестовые данные и объявления таблицы), чтобы помочь больше. Однако, когда это происходит, это происходит потому, что при объединении 2 таблиц вы получаете каждую комбинацию строк 2 таблиц на основе их условий соединения. Не проблема с обычным отношением «один ко многим», когда вы хотите суммировать многие. Но здесь у вас много к одному, и один подсчитывается много раз. Чтобы обойти это, вам нужно использовать подзапрос, чтобы получить каждое из итогов (сгруппированных соответствующим образом) и присоединить этот подзапрос к вашему основному запросу.
Ответ №1:
Не проверено (для этого недостаточно подробностей), но выполнение суммы сборов в подзапросе, а затем присоединение, которое даст вам что-то вроде этого:-
SELECT st.family_id,
st.fees_head_id,
st.fees_term_id,
fh.fees_head_name,
ft.full_name,
SUM(st.fees_amount) AS fees_amount,
fp.paid
FROM fees_students_setup st
LEFT JOIN fees_head fh ON fh.fees_head_id = st.fees_head_id
LEFT JOIN fees_term ft ON ft.fees_term_id = st.fees_term_id
LEFT JOIN
(
SELECT fees_head_id, fees_term_id, family_id, academic_start, academic_end, SUM(paid) AS paid
FROM fees_paid
GROUP BY fees_head_id, fees_term_id, family_id, academic_start, academic_end
) fp
ON fp.fees_head_id = st.fees_head_id
AND fp.fees_term_id = st.fees_term_id
AND st.family_id = fp.family_id
AND fp.academic_start = st.academic_start
AND fp.academic_end = st.academic_end
WHERE st.family_id = '316'
AND st.academic_start = '2013-04-01'
AND st.academic_end = '2014-03-31'
AND st.fees_term_id BETWEEN '1' AND '1'
GROUP BY st.fees_head_id, st.fees_term_id
ORDER BY st.fees_term_id
Обратите внимание, что ГРУППА здесь не соответствует стандартам SQL. В нем должны быть все столбцы, не являющиеся агрегированными. В этом случае, если бы было несколько значений (скажем) fees_head_name для комбинации fees_head_id / fees_term_id, то какое возвращаемое значение fees_head_name было бы неопределенным (может быть любым из потенциальных значений).
В этом случае вы вполне можете просто добавить дополнительные имена столбцов в предложение GROUP BY
Комментарии:
1. Эта идея очень полезна. спасибо, что поделились этим. На самом деле я был смущен подзапросом с левым соединением. Но этот синтаксис работает для меня как шарм. Спасибо
2. Я не знаю, но я получил отрицательную оценку за этот вопрос. Если кто-то думает, что это вопрос, пожалуйста, дайте оценку моему вопросу, спасибо.
3. Не знаю, кто отклонил ваш вопрос, но для дальнейшего использования лучше всего вставить полные объявления таблицы и некоторые примеры данных, которые позволяют воссоздать проблему, вставив их в виде текста, а не изображений, чтобы люди могли легко копировать и вставлять их, чтобы проверить себя. Некоторые люди решили отказаться от голосования из-за этого.