在SQL Server中获取缺少日期计算天数和信息

时间:2017-05-14 09:15:54

标签: sql-server-2012

如何使用以前的日期相关数据填充缺失日期相关数据,并获取SQL Server中以前数据的缺失日期之间的天差?

表:dateinfo

CREATE TABLE [dbo].[dateinfo]
(
    [date] [date] NULL
) 
GO

INSERT [dbo].[dateinfo] ([date]) 
VALUES (CAST(N'2016-06-01' AS Date)), 
       (CAST(N'2016-06-02' AS Date)),
       (CAST(N'2016-06-03' AS Date)),
       (CAST(N'2016-06-04' AS Date)), 
       (CAST(N'2016-06-05' AS Date)),
       (CAST(N'2016-06-06' AS Date)),
       (CAST(N'2016-06-07' AS Date)),
       (CAST(N'2016-06-08' AS Date)),
       (CAST(N'2016-06-09' AS Date)),
       (CAST(N'2016-06-10' AS Date)), 
       (CAST(N'2016-06-11' AS Date));
go

CREATE TABLE [dbo].[orders]
(
    [orderid] [int] NULL,
    [orderdate] [date] NULL,
    [cost] [money] NULL
)
GO

INSERT [dbo].[orders] ([orderid], [orderdate], [cost]) 
VALUES (10, CAST(N'2016-06-01' AS Date), 100.0000),
       (11, CAST(N'2016-06-02' AS Date), 200.0000),
       (12, CAST(N'2016-06-05' AS Date), 300.0000),
       (13, CAST(N'2016-06-09' AS Date), 400.0000),
       (14, CAST(N'2016-06-02' AS Date), 700.0000),
       (15, CAST(N'2016-06-09' AS Date), 700.0000);
GO

根据以上数据,我想要下面的数据

date        | orderid | missingdays | cost
------------+---------+-------------+-----
2016-06-01  |  10     |     0       | 100.00
2016-06-02  |  11     |     0       | 200.00
2016-06-02  |  14     |     0       | 700.00
2016-06-03  |  11     |     1       | 200.00
2016-06-03  |  14     |     1       | 700.00
2016-06-04  |  11     |     2       | 200.00
2016-06-04  |  14     |     2       | 700.00
2016-06-05  |  12     |     0       | 300.00
2016-06-06  |  12     |     1       | 300.00
2016-06-07  |  12     |     2       | 300.00
2016-06-08  |  12     |     3       | 300.00
2016-06-09  |  13     |     0       | 400.00
2016-06-09  |  15     |     0       | 700.00

我试过这样:

SELECT d.date,
       o.orderid,
       datediff(DAY, o.orderdate, d.date) AS missingdays,
       o.cost
FROM dateinfo d
INNER JOIN
  (SELECT o.orderid,
          o.orderdate,
          o.cost
   FROM orders o) o ON o.orderdate <= d.date
WHERE d.date BETWEEN '2016-06-01' AND '2016-06-09'

但是上面的查询没有返回预期的结果。

请告诉我如何编写查询以在SQL Server 2012中实现此结果。

1 个答案:

答案 0 :(得分:0)

我认为可以用更简单的方式完成,但是直到有人更好地发布smth,试试这个:

declare @dateinfo table
(
    [date] [date] NULL
) 


INSERT @dateinfo ([date]) 
VALUES (CAST(N'2016-06-01' AS Date)), 
       (CAST(N'2016-06-02' AS Date)),
       (CAST(N'2016-06-03' AS Date)),
       (CAST(N'2016-06-04' AS Date)), 
       (CAST(N'2016-06-05' AS Date)),
       (CAST(N'2016-06-06' AS Date)),
       (CAST(N'2016-06-07' AS Date)),
       (CAST(N'2016-06-08' AS Date)),
       (CAST(N'2016-06-09' AS Date)),
       (CAST(N'2016-06-10' AS Date)), 
       (CAST(N'2016-06-11' AS Date));
declare @orders table
(
    [orderid] [int] NULL,
    [orderdate] [date] NULL,
    [cost] [money] NULL
)


INSERT @orders ([orderid], [orderdate], [cost]) 
VALUES (10, CAST(N'2016-06-01' AS Date), 100.0000),
       (11, CAST(N'2016-06-02' AS Date), 200.0000),
       (12, CAST(N'2016-06-05' AS Date), 300.0000),
       (13, CAST(N'2016-06-09' AS Date), 400.0000),
       (14, CAST(N'2016-06-02' AS Date), 700.0000),
       (15, CAST(N'2016-06-09' AS Date), 700.0000);



with c as 
( 
  select orderdate as cur, 
         lead(orderdate) over(order by orderdate) as nxt 
  from @orders 
),

missing_ranges as
(
select dateadd(day, 1, cur) as rangestart, 
       dateadd(day, -1, nxt) rangeend,
       cur as prev_dt 
from c 
where datediff(day, cur, nxt) > 1
)

select d.date,
       o.orderid,
       datediff(day, o.orderdate, d.date) as missingdays,
       o.cost
from @dateinfo d
     left join missing_ranges r
         on  d.date between r.rangestart and r.rangeend
     left join  @orders o 
         on d.date =  o.orderdate or  r.prev_dt =  o.orderdate
where d.date between '2016-06-01' and '2016-06-09'