sql - 从日期列表中汇总日期

标签 sql sql-server t-sql

我有一个表,其中包含 id 列以及有效性开始日期和结束日期列。 每个 ID 有多个有效日期范围。

我想尽量减少记录,并尽可能为每组连续日期制作一行。

    declare @tbl table (cid int, st_date int, end_date int )


    insert into @tbl  (cid, st_date,end_date)  
    values (1,20190110,20190111),  
    (1,20190111,20190117), 
    (1,20190117,20190123), 
    (2,20190101,20190117), 
    (2,20190119,20190123),
    (2,20190123,20190127)

所需输出:

cid    st_date      end_date

  1    20190110     20190123

  2    20190101     20190117

  2    20190119     20190127

最佳答案

这是一个间隙和岛屿问题。但它正在处理(可能)重叠的间隔。对于通用解决方案,我建议:

select cid, min(st_date) as st_date, max(end_date) as end_date
from (select t.*,
             sum(case when max_prev_ed >= st_date then 0 else 1 end) over (partition by cid order by st_date) as grp
      from (select t.*, max(end_date) over (partition by cid order by st_date rows between unbounded preceding and 1 preceding) as max_prev_ed
            from @tbl t
           ) t
     ) t
group by cid, grp;

Here是一个数据库<> fiddle 。

这是一个强大的解决方案,适用于以下情况:

  • 超过一天的重叠。
  • 将一个间隔完全包含在另一个间隔中。

关于sql - 从日期列表中汇总日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56063866/

相关文章:

sql - 在 Oracle SQL 查询的结果中包含列名?

sql-server - Delphi 6、ADO、MS 数据库 "Date"字段与 ftWideString 相同

sql - 根据二叉树的祖先向左或向右

sql - CTE 可以提高性能吗?

java - 是否有 java.sql.Connection 类与 SQL Server sp_resetconnection 功能等效的函数?

MySQL 查询结果和

sql - 在Select语句中使用函数进行转换

sql - 检测有序列表中变化的函数

sql-server - SQL 中的大规模单词替换

php - MYSQL 选择字符串中所有子字符串都存在的位置