CREATE AS SELECT *,但从另一张表获得一列

时间:2018-06-27 12:15:56

标签: sql oracle plsql

我需要使用CREATE AS SELECT语句“重新创建”超过50个表(在Oracle中)。但是,所有这些表都将使用来自另一表的数据来修改一列。有没有一种方法可以在不声明SELECT语句中的每一列的情况下实现这一目标?

类似的东西:

CREATE TABLE table_name_copy AS SELECT *, (SELECT col_name FROM other_table WHERE other_table.col_id = table_name.col_id) AS col_name FROM table_name`

基本上在所有表上都有一个列,需要用other_table列中的数据替换。

4 个答案:

答案 0 :(得分:2)

这样生成SQL字符串:

SELECT 'CREATE TABLE table_name_copy AS SELECT '
    || LISTAGG (column_name, ', ') WITHIN GROUP (ORDER BY column_name)
    || ', (SELECT col_name FROM other_table 
           WHERE other_table.col_id = table_name.col_id) AS col_name'
    || ' FROM table_name'
FROM all_tab_cols
WHERE owner = 'OWNER'
AND table_name = 'TABLE_NAME'
AND column_name != 'COL_NAME'

如果要运行以上语句,可以使用EXECUTE IMMEDIATE

DECLARE
  v_sql VARCHAR2(10000);
BEGIN
  SELECT 'CREATE TABLE table_name_copy AS SELECT '
      || LISTAGG (column_name, ', ') WITHIN GROUP (ORDER BY column_name)
      || ', (SELECT col_name FROM other_table 
             WHERE other_table.col_id = table_name.col_id) AS col_name'
      || ' FROM table_name'
  INTO v_sql
  FROM all_tab_cols
  WHERE owner = 'OWNER'
  AND table_name = 'TABLE_NAME'
  AND column_name != 'COL_NAME';

  EXECUTE IMMEDIATE v_sql;
END;
/

答案 1 :(得分:1)

如果两个联接表的col_id列均固定,

您可以通过以下模式使用user_tab_columnsuser_tables词典视图通过以下机制生成名为“ table_name _copy”的新表:

declare
 v_ddl varchar2(4000); 
 v_cln varchar2(400); 
begin
 for c in ( select * 
              from user_tables t 
             where t.table_name in
             ( select c.table_name 
                 from user_tab_columns c
                where c.column_name = 'COL_ID'  ) 
             order by t.table_name )
 loop    
   v_ddl := 'create table '||c.table_name||'_copy as 
                      select ';
   for d in ( select listagg('t1.'||column_name, ',') within group ( order by column_name ) cln 
                from user_tab_columns 
               where table_name = c.table_name 
                 and column_name != 'COL_ID' )                   
   loop
    v_cln := v_cln||d.cln;  
   end loop;
       v_ddl := v_ddl||v_cln;                       
       v_ddl := v_ddl||', t2.col_id t2_id 
        from '||c.table_name||' t1 
        left outer join other_table t2 on ( t1.col_id = t2.col_id )';

       execute immediate v_ddl;                    
       v_ddl := null;
       v_cln := null;
 end loop;
end;

答案 2 :(得分:0)

也许您可以使用简单的联接和星号从第一个表返回所有列,像这样:

CREATE TABLE table_name_copy AS 
  SELECT * FROM (
    SELECT tab1.*, tab2.column_name 
    FROM table_name tab1 LEFT JOIN other_table tab2 ON tab1.col_id = tab2.col_id
  );

答案 3 :(得分:0)

我会尝试的(但是我没有Oracle SQL可以测试,所以请让我从疑问中受益)

CREATE TABLE table_name_copy AS 

SELECT * FROM (
               SELECT *, (SELECT col_name FROM other_table WHERE other_table.col_id = table_name.col_id) as col_name 

               FROM table_name`
               )

编辑: 然后运行

ALTER TABLE table_name_copy DROP COLUMN <old column>
删除您不再需要的列