选择Oracle中2个日期时间列之间的日期的所有行

时间:2016-12-26 10:36:26

标签: oracle

表格中的列是

ID  Name   SDate            EDate            RNo
1    abc   12/27/2016     12/31/2016       12345

结果应该是

ID  Name   SDate            EDate       MDate              RNo
1    abc   12/27/2016     12/31/2016    12/27/2016         12345
1    abc   12/27/2016     12/31/2016    12/28/2016         12345
1    abc   12/27/2016     12/31/2016    12/29/2016         12345
1    abc   12/27/2016     12/31/2016    12/30/2016         12345
1    abc   12/27/2016     12/31/2016    12/31/2016         12345

1 个答案:

答案 0 :(得分:2)

方法1:使用嵌套表

定义日期类型:

create type tp as table of date;
/

然后使用:

select ID, Name, SDate, EDate, x.column_value MDate, RNo
from YOUR_TABLE,
table(cast(multiset(
  select SDate + level - 1
  from dual
  connect by SDate + level - 1 <= EDate
) as tp)) x;

方法2:仅使用

连接

您可以使用分层查询 - CONNECT BY来执行此操作:

select ID, Name, SDate, EDate, 
  sDate + level - 1 MDate,
  RNo
from table
connect by sDate + level - 1 <= EDate;

如果源表只有一行,则上述情况有效。

如果ID 唯一,则下面应该有效:

select ID, Name, SDate, EDate, 
  sDate + level - 1 MDate,
  RNo
from table
connect by sDate + level - 1 <= EDate
and prior id = id
and prior sys_guid() is not null;

如果表格中有复合键,则其所有列上的join与我上面id的方式相同。

方法3:使用连接和传播差异

使用CTE

with spread(lvl) as (
    select level - 1
    from (
        select max(EDate - SDate) + 1 maxdiff
        from my_table
    ) connect by level <= maxdiff
)
select t.id, t.Name, t.SDate, t.EDate,
    SDate + lvl MDate
from my_table t inner join spread s
on EDate - SDate >= lvl;

没有CTE

select t.id, t.Name, t.SDate, t.EDate,
    SDate + lvl MDate
from my_table t
inner join (
    select level - 1 lvl
    from (
        select max(EDate - SDate) + 1 maxdiff
        from my_table
    ) connect by level <= maxdiff
) s
on EDate - SDate >= lvl;