假设网络上有以下数据:
Id Start Date End Date
1 2016-02-12 2016-02-19
2 2016-02-15 2016-02-22
3 2016-03-14 2016-03-20
4 2016-03-12 2016-03-22
我想计算没有日期重复的日期编号。 例如 从开始到结束的第一行日计数是8天 对于从开始到结束的第二行日计数是8天,但它与第一行有4天重叠,我不想计算它。 第三天的日数是......
答案 0 :(得分:1)
我不确定您是想要每行的天数还是仅需要总天数,因此我将展示一种方法来获取这两个选项:
首先,创建并填充样本表:
DECLARE @Table as TABLE
(
t_Id int identity(1,1),
t_start date,
t_end date
)
INSERT INTO @Table (t_start, t_end) VALUES
('2016-02-12', '2016-02-19'),
('2016-02-15', '2016-02-22'),
('2016-03-14', '2016-03-20'),
('2016-03-12', '2016-03-22')
现在,要获得每行的总和,省略行与上一行重叠的天数,您可以执行以下操作:
使用CTE和LAG()
窗口函数来获取上一行的结束日期,
并使用ISNULL
获取最小日期值,如果它是第一行:
;WITH CTE AS
(
SELECT t_Id, t_start, t_end, ISNULL(LAG(t_end) OVER (ORDER BY t_start), '0001-01-01') As prev_end
FROM @Table
)
从该CTE中选择,使用CASE
查看前一条记录是否与当前记录重叠。如果是,则从计数中减去重叠天数:
SELECT t_Id,
t_start,
t_end,
CASE WHEN prev_end < t_start THEN
DATEDIFF(DAY, t_start, t_end)
ELSE
DATEDIFF(DAY, t_start, t_end) - DATEDIFF(DAY, t_start, prev_end)
END As number_of_days
FROM CTE
结果:
t_Id t_start t_end number_of_days
----------- ---------- ---------- --------------
1 2016-02-12 2016-02-19 7
2 2016-02-15 2016-02-22 3
4 2016-03-12 2016-03-22 10
3 2016-03-14 2016-03-20 -2 -- note that the prev row ends after this one.
要获得总天数,您只需将第二个查询包装在另一个cte中并选择sum(number_of_days)
:
;WITH CTE1 AS
(
SELECT t_Id, t_start, t_end, LAG(t_end) OVER (ORDER BY t_start) As prev_end
FROM @Table
), CTE2 As
(
SELECT t_Id,
t_start,
t_end,
CASE WHEN ISNULL(prev_end, '0001-01-01') < t_start THEN
DATEDIFF(DAY, t_start, t_end)
ELSE
DATEDIFF(DAY, t_start, t_end) - DATEDIFF(DAY, t_start, prev_end)
END As number_of_days
FROM CTE1
)
SELECT SUM(number_of_days)
FROM CTE2
结果是18。
答案 1 :(得分:0)
INSERT INTO dbo.Duration(startDate,endDate) VALUES('2007-05-06,'2007-05-07');
SELECT DATEDIFF(day,startDate,endDate) AS 'Duration' FROM dbo.WhatEver;
返回:1