You can build the whole statement from information in the system catalog (or information schema) and execute it dynamically with a DO
command. That's what I would do.
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$;
Assuming that tab1
and tab2
are visible in your search_path
.
Produces and executes what you requested exactly. Just replace dummy table and column names with your real names.
Read about format()
and string_agg()
in the manual.
More information in these related answers:
Table name as a PostgreSQL function parameter
Prepend table name to each column in a result set in SQL? (Postgres specifically)