2

我有个问题。我有 4 张桌子:

Invoice_Payment、发票、客户和日历

基本上,我有以下查询,它运行良好,除了没有 date_due 的月份不返回。IE 只会返回带有 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 Calendar ON 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)

任何帮助表示赞赏。

4

3 回答 3

5

听起来您正在尝试查找范围内所有日期的值,无论是否存在值。假设我们有一个结构如下的日历表:

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)
于 2011-01-16T06:54:01.177 回答
1

我遇到了类似的问题,并通过将非日历表条件移出 WHERE 子句并进入联接来解决它。在这里查看我的完整解释:https ://gist.github.com/1137089

在您的情况下,您需要将表 1、表 2、表 3 分解为 x=y 上的左连接表 1 等...

于 2011-08-11T01:15:26.617 回答
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)

祝你好运!

于 2011-01-16T06:31:30.260 回答