如何使用以前的日期相关数据填充缺失日期相关数据,并获取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中实现此结果。
答案 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'