PostgreSQL无需写全列名实现表间按指定列去重拷贝行的正确语法是什么?
错误原因
你写的INSERT INTO table2 (*)语法不被PostgreSQL支持,INSERT语句的目标列列表不允许使用*作为通配符,因此触发语法错误。
正确实现方案
如果table2和table1的表结构完全一致(列数、列顺序、列类型完全兼容),直接省略INSERT后的列列表即可,不需要手动枚举所有列:
INSERT INTO table2 SELECT DISTINCT ON (col1) * FROM table1 -- 必须添加ORDER BY,确保col1重复时取到你预期的行,示例为取col2最大的行,可按需调整规则 ORDER BY col1, col2 DESC;
补充方案(表结构不完全匹配时使用)
如果两个表结构有差异,你可以通过系统视图快速生成所有列名,不需要手动敲100+列:
-- 执行该查询可直接得到table1所有列的逗号分隔列表,复制后即可用到INSERT/SELECT语句中 SELECT string_agg(quote_ident(column_name), ', ' ORDER BY ordinal_position) FROM information_schema.columns WHERE table_name = 'table1' AND table_schema = 'public';
注意事项
DISTINCT ON要求ORDER BY的第一个排序字段必须是DISTINCT ON中指定的去重字段,否则去重结果不可控,数据库会随机返回重复组内的任意一行- 插入大批量数据前,可以先临时关闭
table2的非必要索引和约束,插入完成后再重建,可大幅提升写入效率
内容的提问来源于stack exchange,提问作者Thetafinity
相关产品推荐
相关产品推荐

