查找两个日期之间缺失的日期范围

舒巴姆库勒

我有包含某些日期范围数据的表格。当用户选择开始日期和结束日期时,结果集将类似于这两个日期之间的所有日期范围以及这两个日期之间的所有缺失日期范围。
例如:
DateRangesTable

ID| fromdate  | todate    |
----------------------------
1 | 5-May-21  | 10-May-21 |
2 | 17-May-21 | 25-May-21 |

这是我的主表,我在下面提到了我想要上表的所有结果集

如果用户选择:5月- 202125月- 2021
预期结果:

ID| fromdate  | todate    |
----------------------------
1 | 5-May-21  | 10-May-21 |
0 | 11-May-21 | 16-May-21 |
2 | 17-May-21 | 25-May-21 |

如果用户选择:6-月-202123月-2021
预期结果:

ID| fromdate  | todate    |
-----------------------------
1 | 6-May-21  | 10-May-21 |
0 | 11-May-21 | 16-May-21 |
2 | 17-May-21 | 23-May-21 |

如果用户选择:1 - 5-202128日- 5-2021
预期结果:

ID| fromdate  | todate    |
----------------------------
1 | 1-May-21  | 4-May-21  |
1 | 5-May-21  | 10-May-21 |
0 | 11-May-21 | 16-May-21 |
2 | 17-May-21 | 25-May-21 |
2 | 26-May-21 | 28-May-21 |

这里有一些不相似但试图找到的问题:

SQL 查找丢失的日期范围

SQL如何编写返回缺失日期范围的查询?

提前致谢。

拉努

一张纸条,我假设在这里,为您的最终预期的结果预期的结果是在这里,因为它不匹配预期的结果其他2.最后和第一行的最后一组都有一个值,ID该ISN” t 0,但没有给出他们为什么这样做的解释因此,我假设该值应该0类似于“中间”中的行。

为此,我使用 Tally 来获取您需要的日期范围之间的所有日期;Tally 限制为 1,000 行,有点少 3 年,但N如果您需要更多行,您可以交叉加入更多行。然后我使用该计数来创建内联日历表。接下来,我LEFT JOIN将日历添加到您的数据中,并使用间隙和孤岛方法将值分组。最后,我汇总这些组,获取每个组的日期MINMAX日期:

USE Sandbox;
GO

CREATE TABLE dbo.YourTable (ID int,
                            FromDate date,
                            ToDate date);
INSERT INTO dbo.YourTable
VALUES(1,'20210505','20210510'),
      (2,'20210517','20210525');
GO

DECLARE @StartDate date = '20210501',
        @EndDate date = '20210528';

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT 0 AS I
    UNION ALL
    SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate))
           ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3), --1000 days
Dates AS(
    SELECT DATEADD(DAY, T.I, @StartDate) AS [Date],
           T.I
    FROM Tally T),
Grps AS(
    SELECT D.[Date],
           YT.ID,
           D.I - ROW_NUMBER() OVER (PARTITION BY ID ORDER BY D.[Date]) AS Grp
    FROM Dates D
         LEFT JOIN dbo.YourTable YT ON D.[Date] >= YT.FromDate AND D.[Date] <= YT.ToDate)
SELECT ISNULL(MAX(G.ID),0) AS ID,
       MIN(G.[Date]) AS FromDate,
       MAX(G.[Date]) AS ToDate
FROM Grps G
GROUP BY G.Grp
ORDER BY FromDate ASC;

GO
DROP TABLE dbo.YourTable;
                          

数据库<>小提琴

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章