【问题标题】:Oracle Insert query from a tableOracle 从表中插入查询
【发布时间】:2015-11-11 12:24:37
【问题描述】:

我有一个如下所示的表格:

表1

column1 column2 column3
1       2       3 
a       6       9 
b       8       7 

我需要将此数据以这种格式复制到另一个表中:

表2

column_name value
column1     1
column1     a
column1     b
column2     2
column2     6
column2     8
column3     3
column3     9
column3     7

有 100 多个表,例如 table1,有数百万行。我需要把它复制到 table2 中。

所以,我打算这样写:

INSERT INTO table2
(column_name, value)
SELECT 'column1', column1
FROM table1;

INSERT INTO table2
(column_name, value)
SELECT 'column2', column2
FROM table1;

INSERT INTO table2
(column_name, value)
SELECT 'column3', column3
FROM table1;

我有 80 个这样的列。有没有一种有效的方法来编写这个也可以在 Oracle 中快速复制数据?

编辑:更改示例数据集以包含不同类型的数据。如果我使用 unpivot,它会给我:

ORA-01790: 表达式必须与对应的表达式具有相同的数据类型

【问题讨论】:

  • 我不知道为什么会有上面这样的要求。但如果必须这样做,只需像上面那样生成 80 个插入语句并一次运行它们。有时你必须粗暴对待硬件。
  • @VarunRao - 拥有键值结构是不是很糟糕?有没有办法优化这个?
  • 编写一个Java应用程序或PL/SQL脚本程序来处理它。
  • @dang 键值结构通常在精心设计的 RDBMS 中不受欢迎。首先,查询起来要困难得多。

标签: sql oracle


【解决方案1】:

为此使用 unpivot

 select * from table1
    unpivot
    (
    "values" for column_names in (column1,column2,column3))

编辑:上面的插入语句用于将数据填充到另一个

create table table2
(
column_names varchar2(1),
"values" varchar2(1)
)
/
    insert into table2
    select * from table1
        unpivot
        (
        "values" for column_names in (column1 as '1',column2 as '2',column3 as '3'))

更新它将column1替换为1,column2替换为2等

 select * from table1
        unpivot
        (
        "values" for column_names in (column1 as '1',column2 as '2',column3 as '3'))

【讨论】:

  • 答案中有语法问题。
  • 我已经更新了查询,现在检查一下。如果您仍然遇到错误,请发布。
  • 我忘了关闭括号现在我已经编辑了请检查。
  • 我必须使用 ID 而不是列名,所以 column1 将被替换为 1,column2 将被替换为 2。如何使用 unpivot 来完成?
  • 另外,请注意数据是不同的数据类型,所以给出错误 - ORA-01790: 表达式必须与相应的表达式具有相同的数据类型
【解决方案2】:

这里有几种反透视数据的方法 - 一种是手动方式,一种是使用 UNPIVOT 关键字。您必须同时测试两者,看看哪一个最适合您的数据集。

with sample_data as (select '1' column1, 2 column2, 3 column3 from dual union all
                     select 'a' column1, 6 column2, 9 column3 from dual union all
                     select 'b' column1, 8 column2, 7 column3 from dual)
select d.id column_id,
       case when d.id = 1 then sd.column1
            when d.id = 2 then to_char(sd.column2)
            when d.id = 3 then to_char(sd.column3)
       end value
from   sample_data sd
       cross join (select level id
                   from   dual
                   connect by level <= 3) d;

COLUMN_NAME VALUE                                   
----------- ----------------------------------------
          1 1                                       
          1 a                                       
          1 b                                       
          2 2                                       
          2 6                                       
          2 8                                       
          3 3                                       
          3 9                                       
          3 7   

with sample_data as (select '1' column1, 2 column2, 3 column3 from dual union all
                     select 'a' column1, 6 column2, 9 column3 from dual union all
                     select 'b' column1, 8 column2, 7 column3 from dual)
select *
from   (select column1,
               to_char(column2) column2,
               to_char(column3) column3
        from   sample_data) sd
unpivot (value for column_id in (column1 as '1', column2 as '2', column3 as '3')) d;

COLUMN_ID VALUE                                   
--------- ----------------------------------------
1         1                                       
2         2                                       
3         3                                       
1         a                                       
2         6                                       
3         9                                       
1         b                                       
2         8                                       
3         7        

在这两个查询中,我都使用了 WITH 子句(又名子查询因子,又名 CTE)来模拟包含数据的表。在您的情况下,您不需要 with 子句。

要将数据插入到另一个表中,您只需在 sql 语句之前附加插入子句,例如:

insert into other table (column_id, value)
select column_id,
       value
from   (select column1,
               to_char(column2) column2,
               to_char(column3) column3
        from   sample_data) sd
unpivot (value for column_id in (column1 as '1', column2 as '2', column3 as '3')) d;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 2018-11-04
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多