如何在 SQL 中的不同行上将多个时间段连接在一起?

Posted

技术标签:

【中文标题】如何在 SQL 中的不同行上将多个时间段连接在一起?【英文标题】:How do I join together multiple time periods over separate rows in SQL? 【发布时间】:2016-09-16 15:37:24 【问题描述】:

我有一个包含唯一 ID 的 SQL 表和两列表示时间段(天)的开始和结束。对于每个 unique_id,如果它们可以组合形成一个连续的周期,我想将它们连接在一起。例如,我有:

unique_id   start           end
A           2013-01-01      2013-01-02
A           2013-01-03      2013-01-05
A           2013-01-05      2013-01-07
A           2013-01-07      2013-01-09
A           2013-01-09      2013-01-11
B           2013-01-02      2013-01-03
B           2013-01-05      2013-01-06

我想要:

unique_id   start           end
A           2013-01-01      2013-01-02
A           2013-01-03      2013-01-11
B           2013-01-02      2013-01-03
B           2013-01-05      2013-01-06

我们可以假设没有重叠的时期。

我该怎么做?

【问题讨论】:

你使用什么关系型数据库? 红移。所以基本上是 PostgreSQL。 【参考方案1】:
with TableX as(
 select * from (values ('A','2013-01-01'::date,'2013-01-02'::date),
('A','2013-01-03'::date,'2013-01-05'::date),
('A','2013-01-05'::date,'2013-01-07'::date),
('A','2013-01-07'::date,'2013-01-09'::date),
('A','2013-01-09'::date,'2013-01-11'::date),
('B','2013-01-02'::date,'2013-01-03'::date),
('B','2013-01-05'::date,'2013-01-06'::date),
('C','2013-01-03'::date,'2013-01-05'::date),
('C','2013-01-05'::date,'2013-01-07'::date),
('C','2013-01-07'::date,'2013-01-09'::date),
('C','2013-01-10'::date,'2013-01-12'::date),
('C','2013-01-12'::date,'2013-01-15'::date)
               ) X(unique_id, start, endd)
)


select distinct unique_id,
       min(start) over(partition by unique_id,grp) as start,
       max(endd)   over(partition by unique_id,grp) as endd
  from
  (
   select *, sum(new) over(partition by unique_id order by start) grp
     from
     (
      select A.*,
             case when start=lag(endd) over(partition by unique_id order by start)
                  then 0 else 1 end as new
        from TableX A
     ) B
  ) C
 order by unique_id, start

结果:

unique_id|start     |endd
A        |2013-01-01|2013-01-02
A        |2013-01-03|2013-01-11
B        |2013-01-02|2013-01-03
B        |2013-01-05|2013-01-06
C        |2013-01-03|2013-01-09
C        |2013-01-10|2013-01-15

【讨论】:

以上是关于如何在 SQL 中的不同行上将多个时间段连接在一起?的主要内容,如果未能解决你的问题,请参考以下文章

在Oracle SQL中从同一列的不同行中选择多个变量的值

如何在准备好的语句php中的不同行中插入多条记录

在一个表中的不同行和不同列中查找相同的值SQL

SQL计算GBQ中表中的不同行数

如何在不同列上的名字和姓氏的不同行上搜索多个名称?

SQL查询以选择具有最小值的不同行