如何在 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 中的不同行上将多个时间段连接在一起?的主要内容,如果未能解决你的问题,请参考以下文章