Sql server 2012 获取SQL Server中缺少的日期、计算天数和信息

Sql server 2012 获取SQL Server中缺少的日期、计算天数和信息,sql-server-2012,Sql Server 2012,在SQL Server中,如何使用以前的日期相关数据填充缺少的日期相关数据,并获取缺少的日期与以前数据之间的天数差 表:日期信息 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

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

表:日期信息

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中编写查询以实现此结果。

我认为可以用更简单的方法完成,但在有人更好地发布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'

我认为可以用更简单的方法来完成,但在有人发布更好的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'

使用左连接代替使用左连接也未给出例外结果使用左连接代替使用左连接也未给出例外结果