INSERT SELECT循环

时间:2016-10-28 19:50:45

标签: sql oracle plsql

我正在尝试将数据从一个表传输到另一个表。但是在这个过程中我需要做一些额外的事情,我只是想知道是否可以在SQL或PL / SQL中做这样的事情。

      source                    target
-------------------       ------------------------
| id | name | qty |       | id | source_id | qty |
-------------------       ------------------------
| 1  | test | 2   |       | 1  | 1         | 1   |
-------------------       ------------------------
| 2  | ago  | 1   |       | 2  | 1         | 1   |    
-------------------       ------------------------
                          | 3  | 2         | 1   |
                          -----------------------

这里根据源表中的数量,我必须插入多个记录。数量可以是任何数量。目标表中的ID自动递增。我试过这个

INSERT INTO target (SELECT id, qty FROM source);

但这并没有处理数量循环。

3 个答案:

答案 0 :(得分:1)

纯SQL:

with
     inputs ( id, qty ) as (
       select 1, 2 from dual union all
       select 2, 1 from dual union all
       select 3, 5 from dual
     )
-- end of test data; solution (SQL query) begins below this line
select row_number() over (order by id) as id, id as source_id, 1 as qty
from   inputs
connect by level <= qty
       and prior id = id
       and prior sys_guid() is not null
;

注意 - 如果ID是自动生成的,只需删除row_number().... as id列;其余的没有改变。

ID  SOURCE_ID  QTY
--  ---------  --
 1          1   1
 2          1   1
 3          2   1
 4          3   1
 5          3   1
 6          3   1
 7          3   1
 8          3   1

答案 1 :(得分:0)

INSERT INTO TARGET(source_id, qty)
    WITH
    output
    AS
    (
      SELECT id, qty FROM source
      UNION ALL
      SELECT id, qty - 1 FROM source WHERE qty > 1
    )    
    SELECT
    id, count(*) as qty 
    FROM output
    group by 
    id, quantity
    ORDER BY
    id

答案 2 :(得分:0)

这可以使用SQL。使用CTE生成与源表中的最大qty匹配的行数,并使用非equi JOIN生成行。使用row_number分析函数为其唯一ID 分配每一行(如果您在目标表中有此行,请参阅下面的修改

with gen_numbers(r) as (
select rownum r
from dual
connect by rownum <= (select max(qty) from src) -- our maximum limit of rows needed
)
select
  row_number() over (order by src.id) as id,
  src.id as source_id, 
  1 as qty
from src
join gen_numbers on src.qty <= gen_numbers.r; -- clone rows qty times

请注意,您可以在1的输出中安全地输入constans值qty

您的测试数据:

create table src (id int, name varchar(255), qty int);
insert into src (id, name, qty) 
  select 1, 'test', 2 from dual union all
  select 2, 'ago',  1 from dual
  ;

结果:

ID  SOURCE_ID   QTY
1   2           1
2   2           1
3   1           1

编辑: 由于您的目标ID列已自动递增,因此您不需要row_number。只需指定它就可以执行INSERT

with gen_numbers(r) as (
select rownum r
from dual
connect by rownum <= (select max(qty) from src) -- our maximum limit of rows needed
)
insert into target_table(source_id, qty)
select
  src.id as source_id, 
  1 as qty
from src
join gen_numbers on src.qty <= gen_numbers.r; -- clone rows qty times
order by src.id

请注意,我添加了ORDER BY子句以确保插入值的正确排序。