查询Oracle以在一行中加入日期间隔

时间:2012-09-24 15:13:39

标签: sql oracle date join range

我的问题是如果第二行的开头是第一行结束后的第二行,则加入更多的日期间隔。在所有这些情况下,我应该只有一行。 例如:

id      start           end
10      20120101        20120125
10      20120201        20120225
10      20120226        20120302
10      20120303        20120304

必须是

10      20120101        20120125
10      20120201        20120304

你有什么建议吗?

1 个答案:

答案 0 :(得分:3)

您是否找到了问题的解决方案?

如果没有,这是我的建议:你是否在表格中有这些行,我们称之为“temp_table”,你可以创建一个只保留相关日期的视图:

CREATE VIEW temp_view AS
SELECT id, dd, ROWNUM AS nr
  FROM (
    SELECT s.ID, s.start_date AS dd --for izolated intervals, keep the wtart date
      FROM temp_table s, temp_table prv, temp_table nxt
     WHERE prv.end_date(+) = s.start_date-1 AND prv.ID(+) = s.ID
       AND s.end_date+1 = nxt.start_date(+) AND nxt.ID(+) = s.ID
       AND prv.ID IS NULL AND nxt.ID IS NULL
    UNION
    SELECT s.ID, decode(nxt.id, 
                   NULL, s.end_date, --no next interval => keep the end date
                   decode(prv.id,
                      NULL, s.start_date)  --no previous interval => keep the start date
                  ) AS dd 
      FROM temp_table s, temp_table prv, temp_table nxt
     WHERE prv.end_date(+) = s.start_date-1 AND prv.ID(+) = s.ID
       AND s.end_date+1 = nxt.start_date(+) AND nxt.ID(+) = s.ID
       AND (prv.ID IS NULL OR nxt.ID IS NULL)
    ORDER BY dd   --order all the dates ascending  
  ); 

此视图将返回如下内容:

ID  DD          NR
10  20120101    1
10  20120125    2
10  20120201    3
10  20120304    4

您可以查询类似的内容:

SELECT start_dates.ID, start_dates.dd AS start_date, end_dates.dd AS end_date
  FROM temp_view start_dates, temp_view end_dates 
 WHERE start_dates.ID = end_dates.ID
   AND start_dates.nr+1 = end_dates.nr 
   AND MOD(start_dates.nr,2) = 1 

结果:

ID  START_DATE  END_DATE
10  20120101    20120125
10  20120201    20120304