Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle时间轴报告来自重叠的时间间隔_Sql_Oracle_Intervals - Fatal编程技术网

Sql Oracle时间轴报告来自重叠的时间间隔

Sql Oracle时间轴报告来自重叠的时间间隔,sql,oracle,intervals,Sql,Oracle,Intervals,我使用的是Oracle 10g,我有一个间隔重叠的表。以简化形式: create TABLE INTERVAL_TEST ( STARTDATE DATE NOT NULL, ENDDATE DATE, ITEM VARCHAR2(100) NOT NULL ) insert into INTERVAL_TEST (STARTDATE, ENDDATE, ITEM) values (to_date('2012-01-01', 'YYYY-MM-DD'), null, '

我使用的是Oracle 10g,我有一个间隔重叠的表。以简化形式:

create TABLE INTERVAL_TEST (
    STARTDATE DATE NOT NULL,
    ENDDATE DATE,
    ITEM VARCHAR2(100) NOT NULL
)

insert into INTERVAL_TEST (STARTDATE, ENDDATE, ITEM) values (to_date('2012-01-01', 'YYYY-MM-DD'), null, 'AAA');
insert into INTERVAL_TEST (STARTDATE, ENDDATE, ITEM) values (to_date('2012-02-01', 'YYYY-MM-DD'), to_date('2012-03-01', 'YYYY-MM-DD'), 'BBB');
如您所见,存在重叠条目。第一个字段中的null表示该字段永远有效。 我需要生成一个报告,在时间线上显示历史记录,列出每行的有效项目数。输出中不应存在时间重叠,相反,应为没有变化的每个子间隔列出所有有效项:

START       END          VALID_ITEMS
----------  ----------   --------------
2012-01-01  2012-02-01   AAA
2012-02-01  2012-03-01   AAA, BBB
2012-03-01  NULL         AAA

是否存在生成这种结果的SQL语句

你可以用一句话来表达:

SQL> WITH timeline AS
  2          (SELECT mydate startdate,
  3                  lead(mydate) OVER (ORDER BY mydate) - 1 enddate
  4             FROM (SELECT startdate mydate FROM interval_test
  5                   UNION
  6                   SELECT enddate FROM interval_test)
  7            WHERE mydate IS NOT NULL)
  8  SELECT startdate,
  9         enddate,
 10         max(substr(sys_connect_by_path(item, ','), 2)) items
 11    FROM (SELECT t.startdate,
 12                 t.enddate,
 13                 item,
 14                 row_number() OVER (PARTITION BY t.startdate, t.enddate
 15                                    ORDER BY i.item) rn
 16            FROM    timeline t
 17                 JOIN
 18                    interval_test i
 19                 ON nvl(i.enddate, DATE '9999-12-31') - 1 >= t.startdate
 20                AND i.startdate <= nvl(t.enddate, DATE '9999-12-31'))
 21  START WITH rn = 1
 22  CONNECT BY rn = PRIOR rn + 1
 23         AND startdate = PRIOR startdate
 24  GROUP BY startdate, enddate
 25  ORDER BY startdate;

STARTDATE  ENDDATE    ITEMS
---------- ---------- --------------------
2012-01-01 2012-01-31 AAA
2012-02-01 2012-02-29 AAA,BBB
2012-03-01            AAA
已加入以下查询,该查询列出给定两个日期的一行中的所有项目:

SELECT max(substr(sys_connect_by_path(item, ','), 2)) items
  FROM (SELECT item, row_number() OVER (ORDER BY item) rn
          FROM interval_test
         WHERE nvl(enddate, DATE '9999-12-31') >= :startdate
           AND startdate <= :enddate)
CONNECT BY rn = PRIOR rn + 1
START WITH rn = 1;

它在更复杂的情况下也能很好地工作,我印象深刻:谢谢!Vincent Malgrat的解决方案是一种保证;-:-
SELECT max(substr(sys_connect_by_path(item, ','), 2)) items
  FROM (SELECT item, row_number() OVER (ORDER BY item) rn
          FROM interval_test
         WHERE nvl(enddate, DATE '9999-12-31') >= :startdate
           AND startdate <= :enddate)
CONNECT BY rn = PRIOR rn + 1
START WITH rn = 1;