2011-01-16 6 views
0

Я действительно борюсь с этим запросом. У меня есть 4 таблицы (http://oberto.co.nz/db-sql.png):mySQL Left Join на нескольких таблицах

Invoice_Payement, счет-фактура, клиент и календарь. Я пытаюсь создать отчет, подытожив «paid_amount» col, в Invoice_Payment, по месяцам/годам.

  • Запрос должен включать в себя все месяцы, даже без данных
  • Там запроса необходимо условие (таблица Invoice): registered_id = [ID]

Я пробовал с ниже запроса , который работает, но падает, когда «paid_date» не имеет записей за месяц. Результат заключается в том, что месяц не отображается в результатах

Я добавил таблицу календаря, чтобы решить эту проблему, но не знаю, как оставить ее присоединенным к ней.

SELECT 
    MONTHNAME(Invoice_Payments.date_paid) as month, 
    SUM(Invoice_Payments.paid_amount) AS total 
FROM Invoice, Client, Invoice_Payments 
WHERE Client.registered_id = 1 
AND Client.id = Invoice.client_id 
And Invoice.id = Invoice_Payments.invoice_id 
AND date_paid IS NOT NULL 
GROUP BY YEAR(Invoice_Payments.date_paid), MONTH(Invoice_Payments.date_paid) 

См. Приведенную выше ссылку для базовой диаграммы ERD моего сценария.

База данных: http://oberto.co.nz/ Ожидаемый результат: мой текущий запрос, ниже, будет возвращать что-то вроде:

month  total 
August  5 
September 0 
October 196 
November 205 
December 214 
January 229 

Спасибо за чтение. Я уже отправил этот вопрос, но, думаю, я это плохо сформулировал.

+0

вы хотите просто список итогов за каждый месяц делать? Зачем вам «date_paid IS NOT NULL» в вашем предложении WHERE? Существуют ли фактически фактические платежи в таблице Invoice_Payments с нулевым значением date_paid? – James

ответ

0

Обновлено: P, будет ли это работать?

SELECT YEAR(calendar.date_field) as year, 
MONTHNAME(calendar.date_field) as month, 
SUM(Invoice_Payments.paid_amount) AS total 
FROM calendar 
left outer join invoice_Payments on calendar.date_field = invoice_Payments.date_paid 
left outer join Invoice on invoice_payments.invoice_id = invoice.invoice_id 
left outer join (select * from client where registered_id = 1) as c on c.id = Invoice.client_id 
GROUP BY YEAR(calendar.date_field), MONTH(calendar.date_field) 
+0

Не совсем, но спасибо. Он работает, за исключением того, что не отображаются месяцы с отсутствующими учетными записями Invoice_Payments.date_paid. Вот почему я предполагаю, что мне нужно сделать левое соединение в таблице календаря. – Jarrod

+0

Как насчет этого? – JoshRoss

+0

Почти! Все данные возвращаются правильно, кроме ограничения ... и Client.registered_id = 1 игнорируется. Поэтому я получаю данные, возвращенные для всех Id, а не для указанного Id. Это простой fiX? – Jarrod

0

Проблема заключается, очевидно, в том, что вы не выполняете левое соединение, поэтому решение может состоять в том, чтобы переписать запрос, чтобы использовать синтаксис соединения, в котором вы можете указать, что хотите левое соединение. Что-то вроде

Select * из счета осталось присоединиться к клиенту на client.id = invoice.client_id слева присоединиться

и так далее

+0

Спасибо MTilsted. Я понимаю, что мне нужно левое соединение, и создание * просто * левое соединение - это то, что я могу сделать, но при добавлении с другими условиями - я просто не могу работать. – Jarrod

+0

Ну, похоже, правильный запрос чуть ниже этого ответа:} – MTilsted

0

Это может также работать ...

SELECT MONTHNAME(Invoice_Payments.date_paid) as month, SUM(Invoice_Payments.paid_amount) AS total 
FROM Client 
LEFT OUTER JOIN Invoice ON Client.id = Invoice.client_id 
LEFT OUTER JOIN Invoice_Payments ON Invoice.id = Invoice_Payments.invoice_id 
WHERE Client.registered_id = 1 AND date_paid IS NOT NULL 
GROUP BY YEAR(Invoice_Payments.date_paid), MONTH(Invoice_Payments.date_paid); 
+1

Этот вопрос более года. Можете ли вы объяснить, как ваш ответ улучшается в существующем запросе? – GargantuChet