Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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 基于Startdate和enddate拆分记录_Sql_Oracle - Fatal编程技术网

Sql 基于Startdate和enddate拆分记录

Sql 基于Startdate和enddate拆分记录,sql,oracle,Sql,Oracle,输入集 CMP BND_CD STARTDATE ENDDATE 01 UF 03/15/2010 07/01/2010 01 TRL 03/15/2010 12/15/2014 虚拟数据 CREATE TABLE DATA ( CMP, BND_CD, STARTDATE, ENDDATE ) AS SELECT '01','UF', DATE '2010-03-15', DATE '2010-07-01' FROM DUAL UNION ALL SELECT

输入集

CMP BND_CD STARTDATE  ENDDATE
01  UF     03/15/2010 07/01/2010
01  TRL    03/15/2010 12/15/2014
虚拟数据

CREATE TABLE DATA ( CMP, BND_CD, STARTDATE, ENDDATE ) AS
  SELECT '01','UF',  DATE '2010-03-15', DATE '2010-07-01' FROM DUAL UNION ALL
  SELECT '01','TRL', DATE '2010-03-15', DATE '2010-12-15' FROM DUAL;
我需要输出为3条记录,这将分割TRL/UF记录,即

CMP BND_CD STARTDATE  ENDDATE
01  UF     03/15/2010 07/01/2010
01  TRL    03/15/2010 07/01/2010
01  TRL    07/01/2010 12/15/2014

如果日期范围相互重叠,则应为两张BND_CD的每个CMP代码进行拆分。我们必须根据CMP值对记录进行分组,如果TRL与UF重叠,则应拆分TRL reords,如果UF与TRL重叠,则应拆分UF记录。

查询

SELECT u.cmp,          -- UF values preceding the TRL range
       u.bnd_cd,
       u.start_date,
       LEAST( u.end_date, t.start_date )
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND u.start_date < t.start_date )
UNION ALL
SELECT u.cmp,          -- UF values within the TRL range
       u.bnd_cd,
       GREATEST( u.start_date, t.start_date ),
       LEAST( u.end_date, t.end_date )
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND u.start_date <= t.end_date
           AND u.end_date   >= t.start_date )
UNION ALL
SELECT u.cmp,          -- UF values following the TRL range
       u.bnd_cd,
       GREATEST( u.start_date, t.end_date ),
       u.end_date
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND u.end_date > t.end_date )
UNION ALL
SELECT t.cmp,          -- TRL values preceding the UF range
       t.bnd_cd,
       t.start_date,
       LEAST( t.end_date, u.start_date )
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND t.start_date < u.start_date )
UNION ALL
SELECT t.cmp,          -- TRL values within the UF range
       t.bnd_cd,
       GREATEST( t.start_date, u.start_date ),
       LEAST( t.end_date, u.end_date )
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND t.start_date <= u.end_date
           AND t.end_date   >= u.start_date )
UNION ALL
SELECT t.cmp,          -- TRL values following the UF range
       t.bnd_cd,
       GREATEST( t.start_date, u.end_date ),
       t.end_date
FROM   data t
       INNER JOIN
       data u
       ON (    t.bnd_cd = 'TRL'
           AND u.bnd_cd = 'UF'
           AND t.cmp = u.cmp
           AND t.end_date > u.end_date )
CMP BND_CD START_DATE END_DATE
--- ------ ---------- ----------
01  UF     2010-03-15 2010-07-01
01  TRL    2010-03-15 2010-07-01
01  TRL    2010-07-01 2010-08-01

如果您有更多行,例如另一行的start/end=04/01/2010-08/01/2010会怎么样?@Aleksej那么我们应该再创建一个间隔,作为新记录。我们必须根据CMP值对记录进行分组,然后如果TRL与UF重叠,则应拆分TRL reords,或者如果UF与TRL重叠,则应拆分UF记录。@Aleksej如果将2010年1月4日-2010年1月8日添加为TRL记录,则UF应在2010年1月3日-2010年1月4日、2010年1月1日-2010年1月7日之间拆分。或者,如果将2010年1月4日-2010年1月8日添加为UF记录,则TRL应在2010年1月3日-2010年1月4日,2010年1月4日-2010年1月7日,-2010年1月7日-2010年1月8日,2014年1月8日-2010年1月12日之间进行拆分。@TomJMuthirenthi请不要在注释中添加测试用例-将它们编辑到答案中。我用样本数据编辑了你的答案,但我不能100%确定你的预期结果是什么;因此,请编辑我留下问号以澄清的区域。@TomJMuthirenthi最好是问你想要回答的问题(并包括适当的边缘案例),而不是回答你实际提出的不能完全解决你问题的问题。就目前情况而言,您的第一个示例非常简单,解决的答案几乎肯定不适用于后两种更复杂的情况-因此,如果您只想解决简单的情况,请回滚我的编辑(或重新编辑),但如果您的问题更复杂,请提供适当的信息。