SQL - 使用列名作为值插入

时间:2013-07-12 18:54:12

标签: sql oracle select insert pivot-table

我正在尝试根据table1 中的select 插入到table2 中,但我无法获得正确的语法。 table1中的列名将驱动插入到table2中PD_NO列的值,如下例所示。任何人都可以帮忙吗?

表1:

         (1)     (2)     (3)     (4)     (5)     (6)
| SEQ | PD_01 | PD_02 | PD_03 | PD_04 | PD_05 | PD_06 |
|-----+-------+-------+-------+-------+-------+-------|
| 632 | 10000 |   0   |  500  |   0   | 20000 |   0   |

表2:

| SEQ | PD_NO |  AMT  |
|-----+-------+-------|
| 632 |   1   | 10000 |
|-----+-------+-------|
| 632 |   3   |  500  |
|-----+-------+-------|
| 632 |   5   | 20000 |
|-----+-------+-------|

我知道如果我正在向另一个方向工作(将table2的内容插入table1),我可以执行以下操作:

INSERT INTO table1
SELECT 
      seq,
      SUM (CASE WHEN pd_no = 1 THEN amt ELSE 0 END) p01_amt,
      SUM (CASE WHEN pd_no = 2 THEN amt ELSE 0 END) p02_amt,
      SUM (CASE WHEN pd_no = 3 THEN amt ELSE 0 END) p03_amt,
      SUM (CASE WHEN pd_no = 4 THEN amt ELSE 0 END) p04_amt,
      SUM (CASE WHEN pd_no = 5 THEN amt ELSE 0 END) p05_amt,
      SUM (CASE WHEN pd_no = 6 THEN amt ELSE 0 END) p06_amt
FROM table2;

4 个答案:

答案 0 :(得分:3)

这是Oracle 11提供UNPIVOT子句以供查询使用的典型问题:

insert  into table2(seq, pd_no, amt)
select  seq, pd_no, amt
from    ( select  *
          from    table1
          unpivot (amt for pd_no in (pd_01 as 1, pd_02 as 2, pd_03 as 3, pd_04 as 4, pd_05 as 5, pd_06 as 6))
        );

答案 1 :(得分:2)

在纯sql中,可以这样做:

INSERT INTO table2 ( SEQ , PD_NO,  AMT )
SELECT SEQ, 1 as pd_no, PD_01 FROM Table1
UNION ALL
SELECT SEQ, 2 as pd_no, PD_02 FROM Table1
UNION ALL
SELECT SEQ, 3 as pd_no, PD_03 FROM Table1
UNION ALL
SELECT SEQ, 4 as pd_no, PD_04 FROM Table1
UNION ALL
SELECT SEQ, 5 as pd_no, PD_05 FROM Table1
UNION ALL
SELECT SEQ, 6 as pd_no, PD_06 FROM Table1

某些数据库具有优化的命令,只能读取源表一次(上面的查询读取源表6次),例如在ORACLE中:

INSERT ALL
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 1, PD_01 )
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 2, PD_02 )
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 3, PD_03 )
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 4, PD_04 )
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 5, PD_05 )
INTO table2 ( SEQ , PD_NO,  AMT ) VALUES ( seq, 6, PD_06 )
SELECT * FROM table1

答案 2 :(得分:0)

insert ... select from基于1:1行工作:来自'select'表的一行数据进入'insert'表的一行。您正尝试从源表中取一行并将其转换为目标表中的多行。这不是直接可能的。您必须为每个要拆分的字段运行多个插入/选择:

INSERT INTO table2 (SEQ, PD_NO, AMT) SELECT SEQ, PD_01, AMT FROM table1
INSERT INTO table2 (SEQ, PD_NO, AMT) SELECT SEQ, PD_02, AMT FROM table1
INSERT INTO table2 (SEQ, PD_NO, AMT) SELECT SEQ, PD_03, AMT FROM table1
INSERT INTO table2 (SEQ, PD_NO, AMT) SELECT SEQ, PD_04, AMT FROM table1
etc...

答案 3 :(得分:0)

CREATE TABLE 1to6 (i INT PRIMARY KEY);
INSERT INTO 1to6 (i) VALUES (1), (2), (3), (4), (5), (6);

INSERT INTO table2 (seq, pd_no, amt)
SELECT seq, i, 
 CASE(i)
 WHEN 1 THEN pd_01
 WHEN 2 THEN pd_02
 WHEN 3 THEN pd_03
 WHEN 4 THEN pd_04
 WHEN 5 THEN pd_05
 WHEN 6 THEN pd_06
 END
FROM table1 CROSS JOIN 1to6

重新评论:显然Oracle不支持多行INSERT语法(尽管该语法是标准SQL-99)。您可以一次插入一行:

INSERT INTO 1to6 (i) VALUES (1);
INSERT INTO 1to6 (i) VALUES (2);
INSERT INTO 1to6 (i) VALUES (3);
INSERT INTO 1to6 (i) VALUES (4);
INSERT INTO 1to6 (i) VALUES (5);
INSERT INTO 1to6 (i) VALUES (6);