我有问题。我有4张桌子:
Invoice_Payment,Invoice,Client和Calendar
基本上,我有以下查询,它运行良好,除了没有date_due的月份不返回。 I.E只会返回date_due的月份。
注意:日历表只列出一年中的每一天。它包含一个col调用date_field
数据库:http://oberto.co.nz/jInvoice.txt
预期输出:我当前的查询将返回如下内容:
month total
August 5
September 0
October 196
November 205
December 214
January 229
请注意九月没有退回?这是因为表Invoice_Payment没有date_due记录
我想我必须使用左连接并加入日历表,例如: LEFT JOIN日历在Invoice_Payments.date_paid = Calendar.date_field。但我没有运气
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)
任何帮助表示感谢。
答案 0 :(得分:4)
听起来您正在尝试查找范围内所有日期的值,无论是否存在值。假设我们有一个类似的Calendar表:
Create Table Calendar
(
[Date] not null Primary Key
)
您的查询可能如此(其中X和Y代表您正在调查的范围的开始和结束日期):
Select Year(C.Date), MonthName(C.Date) As Month
, Coalesce(Sum(IP.paid_amount),0) As Total
From Calendar As C
Left Join (Invoice As I
Join Client As C1
On C1.id = I.client_id
And C.registered_id = 1
Join Invoice_Payments As IP
On IP.Invoice_id = I.Id)
On IP.date_paid = C.date
Where C.Date Between X and Y
Group By Year(C.Date), MonthName(C.Date)
从技术上讲,上面的查询应该可以解决问题。但是,另一种方法是使用您在评论中查询的派生表:
Select Year(C.Date), MonthName(C.Date) As Month
, Coalesce(Sum(Z.paid_amount),0) As Total
From Calendar As C
Left Join (
Select IP.date_paid, IP.paid_amount
From Invoice As I
Join Client As C1
On C1.id = I.client_id
And C.registered_id = 1
Join Invoice_Payments As IP
On IP.Invoice_id = I.Id
) As Z
On Z.date_paid = C.date
Where C.Date Between X and Y
Group By Year(C.Date), MonthName(C.Date)
答案 1 :(得分:1)
我遇到了类似的问题并通过将非日历表条件移出WHERE子句并进入连接来解决它。请在此处查看我的完整说明:https://gist.github.com/1137089
在你的情况下,你需要将from table1,table2,table3分解为x = y上的左连接table1 ......
答案 2 :(得分:0)
为了便于阅读,我会明确定义所有联接。
外连接的一个简单示例,它保留第一个表中的所有行,用空值填充第二个表中任何缺少的列:
select column1,
from table1
left outer join table2
on table1.key = table2.key
假设Calendar表是导致您丢失数据的表,这里是您的查询的一个镜头:
SELECT MONTHNAME(Invoice_Payments.date_paid) as month,
SUM(Invoice_Payments.paid_amount)
FROM Invoice
JOIN Client
ON Client.id = Invoice.client_id
AND Client.registered_id = 1
JOIN Invoice_Payments
ON Invoice_Payments.invoice_id = Invoice.id
LEFT OUTER JOIN Calendar
ON Calendar.key = #yourothertable#.key
WHERE date_paid IS NOT NULL
GROUP BY YEAR(Invoice_Payments.date_paid), MONTH(Invoice_Payments.date_paid)
祝你好运!