Требуется подзапрос MySQL с справкой по левому соединению

#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. Не знаю, кто отклонил ваш вопрос, но для дальнейшего использования лучше всего вставить полные объявления таблицы и некоторые примеры данных, которые позволяют воссоздать проблему, вставив их в виде текста, а не изображений, чтобы люди могли легко копировать и вставлять их, чтобы проверить себя. Некоторые люди решили отказаться от голосования из-за этого.