PostgreSQL:移除重复列的查询优化方法求助
移除PostgreSQL CTE中的重复列
看起来你已经精准定位了问题:通过WITH子句生成的20列表里,col2和col1完全重复,想要高效移除这个冗余列,而不是手动挨个列出剩下的19列(毕竟列数不少)。下面给你两种实用方案:
方案1:明确列出所需列(简单直接)
这是你已经尝试过的思路,胜在直观易读,适合一次性的查询场景:
WITH your_generated_table AS ( -- 替换成你的原始WITH子句查询 SELECT 4 AS col1, 4 AS col2, 24 AS col3, /* ... 依次补充到col20 */ UNION ALL SELECT 6, 6, 45, /* ... */ UNION ALL SELECT 5, 5, 66, /* ... */ UNION ALL SELECT 5, 5, 12, /* ... */ ) SELECT col1, col3, col4, ..., col20 -- 跳过col2即可 FROM your_generated_table;
方案2:动态生成列列表(适合多列场景)
如果列数更多或者需要复用逻辑,手动写列名太繁琐,可以利用PostgreSQL的系统表自动拼接需要的列:
步骤1:先把CTE结果存入临时表
系统表无法直接识别CTE的结构,先把结果转成临时表方便后续操作:
WITH your_generated_table AS ( -- 你的原始WITH子句查询 SELECT 4 AS col1, 4 AS col2, 24 AS col3, /* ... 补充到col20 */ UNION ALL SELECT 6, 6, 45, /* ... */ UNION ALL SELECT 5, 5, 66, /* ... */ UNION ALL SELECT 5, 5, 12, /* ... */ ) SELECT * INTO TEMP TABLE temp_result FROM your_generated_table;
步骤2:自动生成目标查询语句
执行下面的SQL,会直接输出排除col2后的完整查询语句:
SELECT format('SELECT %s FROM temp_result', string_agg(attname, ', ')) FROM pg_attribute WHERE attrelid = 'temp_result'::regclass AND attname != 'col2' AND attnum > 0 -- 过滤系统隐藏列 AND NOT attisdropped ORDER BY attnum;
执行后会得到类似这样的结果:
SELECT col1, col3, col4, ..., col20 FROM temp_result
直接复制这个结果执行,就能得到你想要的输出。
小提示
- 确认
col2和col1是每行值都完全一致的重复列,再移除才不会丢失有效数据; - 临时表
temp_result会在当前会话结束后自动删除,不用清理残留; - 如果是高频执行的查询,方案1的性能更优,毕竟动态SQL会多一层解析开销。
内容的提问来源于stack exchange,提问作者rshar
相关产品推荐
相关产品推荐

