即使数据为空,也要获取数据

时间:2014-06-24 16:41:57

标签: sql sql-server join

即使两个日期之间没有订单,我如何获得所有日期?

样本表

OrderID  | Date      | CusID
33942    | 6-21-2014 | 6005
34059    | 6-20-2014 | 4003
53333    | 6-23-2014 | 6005
59234    | 6-23-2014 | 4003

我怎么能得到这个结果?

CusID   | Date      | OrderID |
4003    | 6-20-2004 | 34059   | 
4003    | 6-21-2004 | null    | 
4003    | 6-22-2004 | null    | 
4003    | 6-23-2004 | 59234   | 
6005    | 6-20-2004 | null    | 
6005    | 6-21-2004 | 33942   | 
6005    | 6-22-2004 | null    | 
6005    | 6-23-2004 | 53333   | 

这是我到目前为止所做的。

我创建了一个日历表

CREATE TABLE #Calendar
(
    [CalendarDate] DATETIME
)

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @EndDate = GETDATE()
SET @StartDate = DATEADD(Year, -1, @EndDate)


WHILE @StartDate <= @EndDate
      BEGIN
             INSERT INTO #Calendar
             (
                   CalendarDate
             )
             SELECT
                   @StartDate

             SET @StartDate = DATEADD(dd, 1, @StartDate)
      END 

然后这是我的查询,但没有给我所需的结果

Select t.CusID, c.CalendarDate, t.OrderID 
From #Calendar c 
left outer join
#temp t
ON
CONVERT(VARCHAR(10), c.CalendarDate, 112) = CONVERT(VARCHAR(10), t.Date, 112)
Where c.CalendarDate Between '6-20-2014' and '6-23-2014'
Order By t.Name

1 个答案:

答案 0 :(得分:0)

您可以从日历表开始,但您还需要一个客户表,因为您的样本正在寻找客户和日历日期的每种可能组合。构建完成后,在加入#temp表之前,您将在两者之间进行(罕见)CROSS JOIN。

另外,为了获得最佳效果,只需在日历表中使用Date类型,而不是DateTime,并将#temp.Date列投射到某个日期,而不是转换为串。这将更快 更多

像这样把它们放在一起:

Select c.CalendarDate, t.OrderID t.CusID
From #Calendar c 
CROSS JOIN (select distinct CusID FROM #temp) cus
left outer join #temp t ON c.CalendarDate = cast(t.Date as date)
Where c.CalendarDate Between '2014-06-20' and '2014-06-23'
Order By t.Name

您可能还想在派生表(子查询)中复制where子句,以避免列出不需要的客户。