如何将PostgreSQL动态元查询生成的查询转为临时视图?
如何将动态交叉表查询转为临时视图
你遇到的核心问题是:第一个查询本质是生成SQL语句的字符串,而非直接返回数据,所以常规的视图创建方法只会存储这个字符串,而非执行它得到转置结果。由于目标视图的列数随原表行数动态变化,无法用固定返回类型的函数封装,这里用匿名代码块(DO语句)的动态SQL方案解决:
解决步骤
1. 用匿名代码块动态创建临时视图
DO $$ DECLARE sql_text text; BEGIN -- 获取生成交叉表的SQL并拼接视图创建语句 SELECT 'CREATE TEMP VIEW transposed_tbl AS ' || sql INTO sql_text FROM ( SELECT 'SELECT * FROM crosstab( $ct$SELECT u.attnum, t.rn, u.val FROM (SELECT row_number() OVER () AS rn, * FROM ' || attrelid::regclass || ') t , unnest(ARRAY[' || string_agg(quote_ident(attname) || '::text', ',') || ']) WITH ORDINALITY u(val, attnum) ORDER BY 1, 2$ct$ ) t (attnum bigint, ' || (SELECT string_agg('r'|| rn ||' text', ', ') FROM (SELECT row_number() OVER () AS rn FROM tbl) t) || ')' AS sql FROM pg_attribute WHERE attrelid = 'tbl'::regclass AND attnum > 0 AND NOT attisdropped GROUP BY attrelid ) sub; -- 执行动态SQL完成视图创建 EXECUTE sql_text; END $$;
2. 查询临时视图获取结果
执行完上述代码后,直接查询视图即可得到转置数据:
SELECT * FROM transposed_tbl;
关键说明
- 匿名代码块无需定义固定返回类型,完美适配列数动态变化的场景。
- 代码先生成完整的视图创建SQL,再通过
EXECUTE执行,最终创建的视图直接存储转置后的结果,而非SQL字符串。 - 若原表
tbl的行数发生变化,需重新执行匿名代码块重建视图,因为视图结构不会自动更新。
内容的提问来源于stack exchange,提问作者Randall
相关产品推荐
相关产品推荐

