用日期表填写日期差距

use*_*307 3 sql t-sql join left-join sql-server-2008-r2

我有两张桌子.

与客户和日期的订单表.数据仓库中的日期维度表.

订单表不包含给定月份中每个日期的活动,但我需要返回填充日期和客户的差距的结果集.

例如,我需要这个:

Customer   Date
===============================
Cust1       1/15/2012   
Cust1       1/18/2012
Cust2       1/5/2012
Cust2       1/8/2012

看起来像这样:

Customer   Date
============================
Cust1       1/15/2012   
Cust1       1/16/2012   
Cust1       1/17/2012       
Cust1       1/18/2012
Cust2       1/5/2012
Cust2       1/6/2012
Cust2       1/7/2012
Cust2       1/8/2012

这似乎是左外连接,但它没有返回预期的结果.这是我正在使用的,但这并不是按预期返回日期表中的每个日期.

SELECT o.customer, 
       d.fulldate
FROM   datetable d 
       LEFT OUTER JOIN orders o 
                    ON d.fulldate = o.orderdate 
WHERE  d.calendaryear IN ( 2012 ); 
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 6

问题是您需要所有日期的所有客户。执行 时left outer join,客户字段为 NULL。

下面通过cross join输入客户姓名和日期来设置驱动程序表:

SELECT driver.customer, driver.fulldate, o.amount 
FROM   (select d.fulldate, customer
        from datetable d cross join
             (select customer
              from orders
              where year(orderdate) in (2012)
             ) o
        where d.calendaryear IN ( 2012 )
       ) driver LEFT OUTER JOIN
       orders o 
       ON driver.fulldate = o.orderdate and
          driver.customer = o.customer;
Run Code Online (Sandbox Code Playgroud)

请注意,此版本假定calendaryearyear(orderdate).


Nen*_*vic 5

您可以使用递归CTE获取两个日期之间的所有日期,而无需datetable:

;WITH CTE_MinMax AS
(
    SELECT Customer, MIN(DATE) AS MinDate, MAX(DATE) AS MaxDate
    FROM dbo.orders
    GROUP BY Customer
)
,CTE_Dates AS
(
    SELECT Customer, MinDate AS Date
    FROM CTE_MinMax
    UNION ALL
    SELECT c.Customer, DATEADD(DD,1,Date) FROM CTE_Dates c
    INNER JOIN CTE_MinMax mm ON c.Customer = mm.Customer
    WHERE DATEADD(DD,1,Date) <= mm.MaxDate
)
SELECT c.* , COALESCE(o.Amount, 0)
FROM CTE_Dates c
LEFT JOIN Orders o ON c.Customer = o.Customer AND c.Date = o.Date
ORDER BY Customer, Date
OPTION (MAXRECURSION 0)
Run Code Online (Sandbox Code Playgroud)

SQLFiddle DEMO

  • 如果日期范围变大,递归 CTE 可能会非常慢。如果两者都不存在,为什么不使用数字表、日历表或系统表?您可能会发现 [这个博客系列](http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-3) 很有趣。 (2认同)