我目前正在寻找针对以下问题的 SQL 解决方案:
SQLFiddle作为指导:
我有一个不可为空的开始日期和可以为空的结束日期的列表。根据这个列表,我需要给定开始日期和结束日期之间的总间隔时间。
基于 SQLFiddle
如果我的数据库中只有情况 1,那么结果应该是 2 天。如果我的数据库中有情况 2 和 3,结果应该是 1 天。
我已经考虑了几天了......任何帮助将不胜感激!
问候,基尔
注意:我正在运行 SQL 2012(是否需要任何特殊的新功能)
我目前正在寻找针对以下问题的 SQL 解决方案:
SQLFiddle作为指导:
我有一个不可为空的开始日期和可以为空的结束日期的列表。根据这个列表,我需要给定开始日期和结束日期之间的总间隔时间。
基于 SQLFiddle
如果我的数据库中只有情况 1,那么结果应该是 2 天。如果我的数据库中有情况 2 和 3,结果应该是 1 天。
我已经考虑了几天了......任何帮助将不胜感激!
问候,基尔
注意:我正在运行 SQL 2012(是否需要任何特殊的新功能)
最好的解决方案是创建“日期”表并从那里开始,否则解决方案将无法维护。对于指定范围内的每个日期,您可以检查它是否被 'dateranges' 表中的范围覆盖并获取未覆盖的日期计数。
像这样的东西:
SELECT COUNT(*)
FROM
Dates d
WHERE
d.Date BETWEEN @start AND @end
AND NOT EXISTS
(SELECT *
FROM dateranges r
WHERE d.date BETWEEN r.startdate and ISNULL(r.enddate, d.date)
)
CREATE TABLE Dates (
dt DATETIME NOT NULL PRIMARY KEY);
INSERT INTO Dates VALUES('20081204');
INSERT INTO Dates VALUES('20081205');
INSERT INTO Dates VALUES('20090608');
INSERT INTO Dates VALUES('20090609');
-- missing ranges
SELECT DATEADD(DAY, 1, prev) AS start_gap,
DATEADD(DAY, -1, next) AS end_gap,
DATEDIFF(MONTH, DATEADD(DAY, 1, prev),
DATEADD(DAY, -1, next)) AS month_diff
FROM (
SELECT dt AS prev,
(SELECT MIN(dt)
FROM Dates AS B
WHERE B.dt > A.dt) AS next
FROM Dates AS A) AS T
WHERE DATEDIFF(DAY, prev, next) > 1;
-- existing ranges
SELECT MIN(dt) AS start_range,
MAX(dt) AS end_range
FROM (
SELECT dt,
DATEDIFF(DAY, ROW_NUMBER() OVER(ORDER BY dt), dt) AS grp
FROM Dates) AS D
GROUP BY grp;
DROP TABLE Dates;