我正在使用Postgres 9.1并有两个表(tab1
和tab2
)。我希望创建第三个表(tab3
),其中每列是这些表中各列之间的差异,即tab3.col1 = (tab1.col1 - tab2.col1)
。但是,我的表tab1
和tab2
包含大量列。有没有一种有效的方法来创建表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);
答案 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_path
和format()
。
这些相关答案的更多信息:
string_agg()
Table name as a PostgreSQL function parameter