Oracle中基于日期的行生成

时间:2018-11-29 09:41:29

标签: sql oracle oracle11g

美好的一天,

我有以下格式的数据

ID  Start Date    End Date   
1   01-Nov-2018   01-Nov-2018
2   04-Nov-2018   07-Nov-2018
3   09-Nov-2018   09-Nov-2018
4   11-Nov-2018   12-Nov-2018

我想生成以下输出

ID  Date
1   01-Nov-2018
2   04-Nov-2018
2   05-Nov-2018
2   06-Nov-2018
2   07-Nov-2018
3   09-Nov-2018
4   11-Nov-2018
4   12-Nov-2018

如果我要为单个ID处理它,我知道该怎么做

SELECT
  ,d.ID
  , dv.date_start  start_date
  , dv.date_end    End_Date
  , dv.date_start + Level - 1  the_date
From (SELECT * 
      FROM table_name d
      WHERE d.id = <some_id>) dv
Where (dv.date_start + Level - 1) <= dv.date_end
Connect By Level <= dv.date_end - dv.date_start + 1;

但是,一旦我给出多个ID,它就会变成麻烦,并给出多个重复的日期。感谢是否有人可以帮助我生成所需数据。

2 个答案:

答案 0 :(得分:2)

尝试一下。

SELECT id, 
       start_date + LEVEL - 1 
FROM   t 
CONNECT BY LEVEL <= ( end_date - start_date + 1 ) 
           AND PRIOR id = id 
                     AND PRIOR sys_guid() IS NOT NULL; 

阅读Sys_Guid() in connect by level

Demo

答案 1 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name ( ID, Start_Date, End_Date ) AS
SELECT 1, DATE '2018-11-01', DATE '2018-11-01' FROM DUAL UNION ALL
SELECT 2, DATE '2018-11-04', DATE '2018-11-07' FROM DUAL UNION ALL
SELECT 3, DATE '2018-11-09', DATE '2018-11-09' FROM DUAL UNION ALL
SELECT 4, DATE '2018-11-11', DATE '2018-11-12' FROM DUAL;

查询1

SELECT t.*,
       c.COLUMN_VALUE AS the_date
FROM   table_name t
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT t.start_date + LEVEL - 1
             FROM   DUAL
             CONNECT BY t.start_date + LEVEL - 1 <= t.end_date
           )
           AS SYS.ODCIDATELIST
         )
       ) c

Results

| ID |           START_DATE |             END_DATE |             THE_DATE |
|----|----------------------|----------------------|----------------------|
|  1 | 2018-11-01T00:00:00Z | 2018-11-01T00:00:00Z | 2018-11-01T00:00:00Z |
|  2 | 2018-11-04T00:00:00Z | 2018-11-07T00:00:00Z | 2018-11-04T00:00:00Z |
|  2 | 2018-11-04T00:00:00Z | 2018-11-07T00:00:00Z | 2018-11-05T00:00:00Z |
|  2 | 2018-11-04T00:00:00Z | 2018-11-07T00:00:00Z | 2018-11-06T00:00:00Z |
|  2 | 2018-11-04T00:00:00Z | 2018-11-07T00:00:00Z | 2018-11-07T00:00:00Z |
|  3 | 2018-11-09T00:00:00Z | 2018-11-09T00:00:00Z | 2018-11-09T00:00:00Z |
|  4 | 2018-11-11T00:00:00Z | 2018-11-12T00:00:00Z | 2018-11-11T00:00:00Z |
|  4 | 2018-11-11T00:00:00Z | 2018-11-12T00:00:00Z | 2018-11-12T00:00:00Z |