表 A 数据如下:
        编号        开始时间                结束时间
a 2010-1-4 8:00:00 2010-1-4 9:00:00
a 2010-1-4 8:30:00 2010-1-4 9:00:00
a 2010-1-4 9:30:00 2010-1-4 11:00:00
a 2010-1-4 10:00:00 2010-1-4 11:00:00
a 2010-1-4 13:00:00 2010-1-4 14:00:00
b 2010-1-4 8:00:00 2010-1-4 9:00:00
b 2010-1-4 8:30:00 2010-1-4 9:00:00
b 2010-1-4 8:30:00 2010-1-4 11:00:00
b 2010-1-4 10:00:00 2010-1-4 11:00:00
b 2010-1-4 13:00:00 2010-1-4 14:00:00得到如下结果:
   a    2010-1-4 8:00:00 2010-1-4 9:00:00
   a 2010-1-4 9:30:00 2010-1-4 11:00:00
   a 2010-1-4 13:00:00 2010-1-4 14:00:00
   b 2010-1-4 8:00:00 2010-1-4 11:00:00
   b 2010-1-4 13:00:00 2010-1-4 14:00:00

解决方案 »

  1.   

    SQL> select id,to_char(btime,'yyyy-mm-dd hh24:mi:ss'),to_char(etime,'yyyy-mm-ddhh24:mi:ss') from a;I TO_CHAR(BTIME,'YYYY TO_CHAR(ETIME,'YYYY
    - ------------------- -------------------
    a 2010-01-04 08:00:00 2010-01-04 09:00:00
    a 2010-01-04 08:30:00 2010-01-04 09:00:00
    a 2010-01-04 09:30:00 2010-01-04 11:00:00
    a 2010-01-04 10:00:00 2010-01-04 11:00:00
    a 2010-01-04 13:00:00 2010-01-04 14:00:00
    b 2010-01-04 08:00:00 2010-01-04 09:00:00
    b 2010-01-04 08:30:00 2010-01-04 09:00:00
    b 2010-01-04 08:30:00 2010-01-04 11:00:00
    b 2010-01-04 10:00:00 2010-01-04 11:00:00
    b 2010-01-04 13:00:00 2010-01-04 14:00:0010 rows selected.SQL> select id,to_char(btime,'yyyy-mm-dd hh24:mi:ss'),to_char(etime,'yyyy-mm-ddhh24:mi:ss') from a t
      2  where not exists (select 1 from a where id=t.id and btime<=t.btime and etime>=t.etime and rowid!=t.rowid)
      3  order by id,btime;I TO_CHAR(BTIME,'YYYY TO_CHAR(ETIME,'YYYY
    - ------------------- -------------------
    a 2010-01-04 08:00:00 2010-01-04 09:00:00
    a 2010-01-04 09:30:00 2010-01-04 11:00:00
    a 2010-01-04 13:00:00 2010-01-04 14:00:00
    b 2010-01-04 08:00:00 2010-01-04 09:00:00
    b 2010-01-04 08:30:00 2010-01-04 11:00:00
    b 2010-01-04 13:00:00 2010-01-04 14:00:006 rows selected.SQL>
      

  2.   

    按照楼主的例子,好像是如果有以下数据:
    表 A 数据如下: 
            编号        开始时间                结束时间 
    a 2010-1-4 8:00:00 2010-1-4 9:00:00 
    a 2010-1-4 8:30:00 2010-1-4 10:00:00 应该得到如下结果: 
      a    2010-1-4 8:00:00 2010-1-4 10:00:00 所以1楼的好像还不是很对。。
      

  3.   

    --测试数据
    create table tt as
      select 'a' id,to_date('2010-1-4 8:00:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 9:00:00  ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'a' id,to_date('2010-1-4 8:30:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 9:00:00  ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'a' id,to_date('2010-1-4 9:30:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 11:00:00 ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'a' id,to_date('2010-1-4 10:00:00','yyyy-mm-dd hh24:mi:ss')starttime,to_date(' 2010-1-4 11:00:00','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'a' id,to_date('2010-1-4 13:00:00','yyyy-mm-dd hh24:mi:ss')starttime,to_date(' 2010-1-4 14:00:00','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'b' id,to_date('2010-1-4 8:00:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 9:00:00  ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'b' id,to_date('2010-1-4 8:30:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 9:00:00  ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'b' id,to_date('2010-1-4 8:30:00 ','yyyy-mm-dd hh24:mi:ss')starttime,to_date('2010-1-4 11:00:00 ','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'b' id,to_date('2010-1-4 10:00:00','yyyy-mm-dd hh24:mi:ss')starttime,to_date(' 2010-1-4 11:00:00','yyyy-mm-dd hh24:mi:ss')endtime from dual union all   
      select 'b' id,to_date('2010-1-4 13:00:00','yyyy-mm-dd hh24:mi:ss')starttime,to_date(' 2010-1-4 14:00:00','yyyy-mm-dd hh24:mi:ss')endtime from dual;
    --查询
    with t1 as(select tt.*,row_number()over(partition by id order by endtime,starttime)rn from tt)
    select id,min(starttime),max(endtime) from t1 t
    start with not exists(select 1 from t1 where id=t.id and rn=t.rn-1 and endtime>=t.starttime)
    connect by id=prior id
      and starttime<=prior endtime and rn=prior rn+1
    group by id,rn-level;/*
    ID MIN(STARTTIME) MAX(ENDTIME)
    a 2010-1-4 8:00:00 2010-1-4 9:00:00
    a 2010-1-4 9:30:00 2010-1-4 11:00:00
    a 2010-1-4 13:00:00 2010-1-4 14:00:00
    b 2010-1-4 8:00:00 2010-1-4 11:00:00
    b 2010-1-4 13:00:00 2010-1-4 14:00:00
    */
      

  4.   

    先用row_number()为原表的记录按顺序赋上序号,按id分组,endtime,starttime从小到大排序
    排好序后,判断连续:两条记录间,下一条的starttime>=上一条的endtime,则为连续
    将连续的记录通过connect by树形查询连起来
    然后group by,将连续的记录合并到一条记录中
    可以这么改下,看看group by前的rn和levelwith t1 as(select tt.*,row_number()over(partition by id order by endtime,starttime)rn from tt)
    select id,starttime,endtime,rn,level from t1 t
    start with not exists(select 1 from t1 where id=t.id and rn=t.rn-1 and endtime>=t.starttime)
    connect by id=prior id
      and starttime<=prior endtime and rn=prior rn+1
    ;
      

  5.   

    参考http://topic.csdn.net/u/20090923/13/baaa34b4-184d-4805-b6d4-747ec0845fe6.html
    中的41楼的代码