【问题标题】:How to insert multiple rows from a single row in Oracle如何在Oracle中从单行插入多行
【发布时间】:2017-01-31 17:08:28
【问题描述】:

我在 Oracle 数据库中有下表

src_tbl
id     from_date      thru_date
------------------------------
1      01-JAN-2015    31-oct-2016
2      01-APR-2016    31-DEC-2015
3      01-JUL-2014    31-DEC-2016

我想将 src_tbl 中的行插入到目标表中并创建一个 from_date 和 thru_date 之间每个月的行,如下所示:

tgt_tbl
--------------------------
id           month
1            JAN-2015
1            FEB-2015
1            MAR-2015
...
...
2            APR-2016
2            MAY-2016
2            JUN-2016            
...
...
3            JUL-2014
3            AUG-2014
3            SEP-2014
3            OCT-2014
...

任何建议将不胜感激。

【问题讨论】:

  • 希望你的两个日期列实际上是 DATE 数据类型,而不是字符串......是吗?
  • 2015 在thru_date 中为id = 2 是一个错字,对吗?您应该有一个检查约束以确保thru_date 永远不会早于from_date

标签: oracle


【解决方案1】:
select     id, to_char( add_months(from_date, level - 1), 'MON-yyyy' ) as mth
from       src_tbl
connect by level <= months_between(thru_date + 1, from_date)
       and prior id = id
       and prior sys_guid() is not null
;

注意:正如 cmets 中所讨论的,我假设“环境”保证对于任何 idthru_date 永远不会早于 from_date。如果是,则此查询将产生一行(对于from_date 月),而它可能不应该产生一行。理想情况下,该逻辑条件由基表上的检查约束强制执行。

【讨论】:

  • 有效数据的好解决方案,但对于给定的输入,ID = 2 如果 IMO 不返回任何记录作为 thru_date
  • @MarmiteBomber - 我注意到了这一点,在我的测试中我将第二行更改为有效。我同意你的观点,但我建议数据模型应该使thru_date &gt;= from_date 成为表中的一个约束(而不是必须围绕违反该条件的情况进行编码)。
【解决方案2】:

这里是 SQL SERVER 版本。你肯定能找到 Oracle CTE 语法。 但递归逻辑保持不变。

    create table tbl1(id int, fd date, td date)
    insert into tbl1(id,fd,td)
              Select 1,'1-1-2016','4-1-2016'
    union all select 2,'6-1-2016','8-1-2016'



     ;with c1(fd,td,id,rowid)
     AS
     (
        select fd,td,id,ROW_NUMBER() over (order by id) rowid from tbl1
     ),
     c2(fd,td,id,rowid)
     AS
     (
        select fd,td,id,rowid from c1-- where rowid=1
        union all
        select DATEADD(month,1,c2.fd),c1.td,c1.id,c2.rowid from c1
        join c2 on c2.fd<c1.td and c1.id=c2.id
     )
     select * from c2 order by rowid,fd

【讨论】:

    猜你喜欢
    • 2010-10-27
    • 2012-09-26
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多