【问题标题】:How to insert multiple new records based on record(s) already in the table (in Oracle)?如何根据表中已有的记录(在 Oracle 中)插入多条新记录?
【发布时间】:2013-10-25 09:28:04
【问题描述】:

我想在列 (Type) 中查找具有特定值 (S) 的行 (记录),并根据同一表中的该行插入多行 (例如 2)。

例如,在下面的表 t1 中,我希望为类型为“S”的每一行插入 2 行,具有相同的 ID 和价格,新的计数器值(对此字段没有具体要求,但是计数器用于相同的记录ID 必须不同),Type 将是 'B'。

表示根据下表中的第一条记录(1,1200,S,200)插入2行时,新记录的Counter值必须与ID=1的记录的Counter值不同表(1200 和 1201)。因此,在初始表中有三个类型为“S”的记录,然后在最终表中,对于这些记录中的每一个,都插入了两个类型为“B”的新记录和一个新的计数器值:

ID 计数器类型 价格 ---------------------- 1 1200 S 200 1 1201 T 400 2 1200 吨 500 3 1546 S 100 3 1547 S 70 4 2607 男 250

输出表 t1 将是:

ID 计数器类型 价格 ---------------------- 1 1200 小号 200 1 1202 B 200 1 1203 B 200 1 1201 T 400 2 1200 吨 500 3 1546 小号 100 3 1548 B 100 3 1549 B 100 3 1547 小号 700 3 1550 B 700 3 1552 B 700 4 2607 男 250

【问题讨论】:

  • 只是备注:调用列 ID 然后在其中包含重复值并不是一个好主意。您的 ID 不是用于记录的 ID,而是其他东西。

标签: sql oracle insert multiple-records


【解决方案1】:

你只需要玩两次这个命令:

insert into epn
with w(max) as
(
  select max(t.counter) from t -- useful to get max counter value
)
select t.id, w.max + rownum, 'B', t.price -- max + rownum then gives new values
from t, w
where t.type != 'B'; -- Avoid duplicating rows added 1st time

这给出了:

1   1   1200    S   200
2   1   2617    B   200
3   1   2611    B   200
4   1   1201    T   400
5   1   2618    B   400
6   1   2612    B   400
7   2   1200    T   500
8   2   2613    B   500
9   2   2619    B   500
10  3   1547    S   70
11  3   2609    B   70
12  3   2615    B   70
13  3   1546    S   100
14  3   2614    B   100
15  3   2608    B   100
16  4   2607    M   250
17  4   2610    B   250
18  4   2616    B   250

【讨论】:

  • 但我只需要插入类型为“S”(不是“T”或“M”)的记录。
【解决方案2】:

你需要一个插入选择语句:

insert into t1 (ID, Counter, Type, Price)
select ID, Counter+1, 'B', Price from t1 where Type = 'S'
union all
select ID, Counter+2, 'B', Price from t1 where Type = 'S';

编辑:这是符合您在下面评论中提到的标准的声明。它获取每个 ID 的最大计数器,并将添加条目的计数添加到 ID (1, 2, 3, ...) 中。

insert into t1 (ID, Counter, Type, Price)
select 
  ID, 
  (select max(Counter) from t1 where ID = src.ID) + row_number() over (partition by ID order by Price) as new_counter, 
  'B' as Type, 
  Price
from
(
    select ID, Price 
      from t1 
      join (select * from dual union all select * from dual) twice
      where t1.Type = 'S'
) src;

【讨论】:

  • 但是加 1 或 2 并不一定保证 Counter 的新值在 ID 内是唯一的。真正的表要大得多,我们可以有数百条具有一个特殊 ID 和不同 Counter 值的记录。
  • 谢谢。这里是不是缺少什么:join (select * from dual union all select * from dual) twice?当我运行它时,我在下一行的开头收到“缺少关键字”错误消息。
  • 这里好像少了什么:(select max(Counter) from t1 where ID = src.ID) + row_number() over (partition by ID order by Price) as new_counter(可能在overpartition之间)。因为我在运行它时收到“缺少表达式”错误。
  • 以及函数row_number的“缺少此函数的窗口规范”错误消息。
【解决方案3】:

创建序列 my_SEQ

增加 1

从 1 开始

最小值 1

最大值 999999999

NOCYCLE

无缓存

正餐;

创建表 MY_TABLE1 ( 身份证号码, 柜台号码(20), 输入 varchar2(30), 价格编号 )

插入 my_table1 (id,counter,type,price) 值(my_SEQ.nextval,1200,'S',200);

插入 my_table1 (id,counter,type,price) 值 (my_SEQ.nextval,1300,'B',311);

插入 my_table1 (id,counter,type,price) 值 (my_SEQ.nextval,200,'S',110);

插入 my_table1 (id,counter,type,price) 值 (my_SEQ.nextval,299,'B',329);

从 my_table1 中选择 *

    ID    COUNTER TYPE                                PRICE

    62       1200 S                                     200
    63       1300 B                                     311
    64        200 S                                     110
    65        299 B                                     329

声明

光标 c1 是 select * from My_table1 where type='B';

开始

为REC IN c1

循环

插入 my_table1 (id,counter,type,price)

值(my_SEQ.nextval,rec.counter+1,'Z',rec.price);

结束循环;

结束;

从 my_table1 中选择 *

    ID    COUNTER TYPE                                PRICE

    63       1300 B                                     311
    65        299 B                                     329
    64        200 S                                     110
    62       1200 S                                     200
    66       1301 Z                                     311
    67        300 Z                                     329

已选择 6 行。

因此,在光标中选择 type 为 ='B' 的所有行,然后将它们插入并稍微更改值!希望这可以帮助。你不能使用序列,但添加 rec.id+1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多