所有列的新表,作为两个基表列之间的差异

时间:2014-03-10 03:56:55

标签: postgresql postgresql-9.1 dynamic-sql outer-join create-table

我正在使用Postgres 9.1并有两个表(tab1tab2)。我希望创建第三个表(tab3),其中每列是这些表中各列之间的差异,即tab3.col1 = (tab1.col1 - tab2.col1)。但是,我的表tab1tab2包含大量列。有没有一种有效的方法来创建表tab3

如果我要硬编码我想要的输出,我打算使用下面的代码。但是我希望避免这种情况,因为我有超过60列要创建并希望避免任何硬编码错误。两个表中的列的顺序可能不同,但命名在表之间是一致的。

CREATE TABLE tab3 AS
  SELECT a.col1_01 - b.col2_01 AS col3_01,
         a.col1_02 - b.col2_02 AS col3_02,
         ...
         ...
   FROM tab1 a FULL JOIN tab2 b USING (permno, datadate);

1 个答案:

答案 0 :(得分:1)

您可以根据系统目录(或信息模式)中的信息构建整个语句,并使用DO command动态执行它。这就是我要做的。

DO
$do$
BEGIN

EXECUTE (
SELECT 'CREATE TABLE tab3 AS
SELECT '
|| string_agg(format('a.%1$I - b.%1$I AS %1$I', attname)
            , E'\n     , ' ORDER BY attnum)
|| '
FROM   tab1      a
FULL   JOIN tab2 b USING (permno, datadate)'
FROM   pg_attribute
WHERE  attrelid = 'tab1'::regclass
AND    attnum > 0        -- exclude system columns (neg. attnum)
AND    NOT attisdropped  -- no dropped (dead) columns
);

END
$do$;

假设tab1中显示tab2和{{1}}。

生成并执行您所要求的完全。只需用您的真实姓名替换虚拟表名和列名。

阅读手册中的search_pathformat()

这些相关答案的更多信息:
string_agg()
Table name as a PostgreSQL function parameter

相关问题