2016-03-03 22 views
0

我有多行,其开始时间为&结束时间列彼此重叠。用于重叠时间戳的SQL查询

我需要使用SQL查找不同的时间间隔。

的样本数据:

(6 -> 7) 
(6.30 -> 6.45) 
(8 -> 9) 
(8.30 -> 9.30) 

输出:

(6 -> 7) 
(8 -> 9.30) 
+2

什么dbms?时间戳如何存储? – Yossi

+1

Vertica db。 时间戳格式的开始时间/结束时间:2016-03-03 14:19:05 – Neha

+0

这是一个* gaps&islands *问题,已经在SO上回答了几次:http://stackoverflow.com/questions/标签/ gap-and-islands + sql Vertica支持分析函数,所以它应该很容易修改其中一个答案... – dnoeth

回答

0

Vertica的具有非常强大的 “时间序列” 和 “条件事件” 分析功能。你的问题就可以轻松解决这样...

假设这是你开始表:

SQL> select * from otest ; 
     t1   |   t2   
--------------------+-------------------- 
2016-03-04 06:00:00 | 2016-03-04 07:00:00 
2016-03-04 06:30:00 | 2016-03-04 06:45:00 
2016-03-04 08:00:00 | 2016-03-04 09:00:00 
2016-03-04 08:30:00 | 2016-03-04 09:30:00 
(4 rows) 

哪里t1是您开始时间戳t2是你结束时间戳。所有你需要做的是:

SQL> select 
     min(a.t1), 
     max(a.t2) 
    from ( 
     select 
      t1, 
      t2, 
      conditional_true_event (t1 >= lag(t2)) 
       over (order by t1) as cte 
     from otest) a 
    group by cte 
    order by 1 ; 

     min   |   max   
--------------------+-------------------- 
2016-03-04 06:00:00 | 2016-03-04 07:00:00 
2016-03-04 08:00:00 | 2016-03-04 09:30:00 
(2 rows) 
0

我会评论毛罗的,但我没有代表。不幸的是,他的回答没有考虑到当你有两个以上的重叠时期会发生什么。

这里是我的解决方案:

--create the table for the purposes of this demo 
drop schema if exists TEST1 cascade;  
create schema if not exists TEST1; 
drop table if exists  TEST1.otest; 
create table if not exists TEST1.otest(t1 datetime, t2 datetime); 

--create some example data 
--example where 2nd period is entirely inside the first 
insert into TEST1.otest(t1, t2) select '2016-03-04 06:00:00' ,'2016-03-04 07:00:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 06:30:00' ,'2016-03-04 06:45:00'; 

--example of multiple consecutive periods 
insert into TEST1.otest(t1, t2) select '2016-03-04 08:00:00' ,'2016-03-04 09:00:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 08:15:00' ,'2016-03-04 08:25:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 08:26:00' ,'2016-03-04 08:27:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 08:28:00' ,'2016-03-04 08:29:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 08:30:00' ,'2016-03-04 09:30:00'; 

--example of another overlapping period extending the end time 
insert into TEST1.otest(t1, t2) select '2016-03-04 10:00:00' ,'2016-03-04 10:30:00'; 
insert into TEST1.otest(t1, t2) select '2016-03-04 10:15:00' ,'2016-03-04 10:45:00'; 

--query syntax 
with i as (select * from TEST1.otest) 
,i2 as (select * ,max(t2) over (order by t1) as maxT2 from i) 
,i3 as (select *, lag(i2.maxT2) over (order by t1) as laggedMaxT2 from i2) 
,i4 as (select *, conditional_true_event(i3.t1 > i3.laggedMaxT2) over (order by t1) as grouper from i3) 
select min(t1) as collapsedT1, max(t2) as collapsedT2 from i4 group by grouper 
order by collapsedT1; 

--results 
    collapsedT1   |collapsedT2   | 
--------------------|--------------------| 
2016-03-04 06:00:00 |2016-03-04 07:00:00 | 
2016-03-04 08:00:00 |2016-03-04 09:30:00 | 
2016-03-04 10:00:00 |2016-03-04 10:45:00 | 

编辑:如果你的数据被其他栏目分类,记得分区的条款添加到最大,conditional_true_event和滞后分析,或者你可以得到不确定的结果。