简介
在各种应用中,我们经常会遇到分组和提取的需求给定输入的连续日期范围。此任务出现在日历填充或数据分析等情况下。通过利用 SQL 强大的功能,我们可以高效地解决问题,而不需要复杂的联接或递归 CTE。
问题定义
考虑一个名为“InfoDate”的列,包含一系列日期,如下所示:
InfoDate |
---|
2013-12-04 |
2013-12-05 |
2013-12-06 |
2013-12-09 |
2013-12-10 |
2014-01-01 |
2014-01-02 |
2014-01-03 |
2014-01-06 |
2014-01-07 |
2014-01-29 |
2014-01-30 |
2014-01-31 |
2014-02-03 |
2014-02-04 |
目标是识别每个连续的日期范围并提取每个间隔的开始日期和结束日期。如下例所示,连续的日期应组合在一起形成一个范围:
StartDate | EndDate |
---|---|
2013-12-04 | 2013-12-06 |
2013-12-09 | 2013-12-10 |
2014-01-01 | 2014-01-03 |
2014-01-06 | 2014-01-07 |
2014-01-29 | 2014-01-31 |
2014-02-03 | 2014-02-04 |
SQL 解决方案
要使用 SQL 实现此结果,我们使用一种结合使用行编号和日期差异的技术。通过使用 ROW_NUMBER() 函数,我们为“InfoDate”列的每一行分配一个序号(“i”),并创建一个名为“d”的列。此列表示每个日期与其相应行号之间的差异。
WITH t AS ( SELECT InfoDate d,ROW_NUMBER() OVER(ORDER BY InfoDate) i FROM @d GROUP BY InfoDate )
以下步骤涉及按“i”列和“d”列之间的差异对行进行分组 (DATEDIFF(day,i, d))。这种分组允许我们识别连续的日期,因为它们将共享相同的差值。
SELECT MIN(d),MAX(d) FROM t GROUP BY DATEDIFF(day,i,d)
通过在每个组中使用 MIN() 和 MAX() 函数,我们可以确定
| StartDate | EndDate | |---|---| | 2013-12-04 | 2013-12-06 | | 2013-12-09 | 2013-12-10 | | 2014-01-01 | 2014-01-03 | | 2014-01-06 | 2014-01-07 | | 2014-01-29 | 2014-01-31 | | 2014-02-03 | 2014-02-04 |
通过这种方式,我们使用纯粹基于 SQL 的方法高效地提取了连续的日期范围。
以上是如何在SQL中高效检测和提取连续的日期范围?的详细内容。更多信息请关注PHP中文网其他相关文章!