You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中删除表内完全重复行并保留一行的方案咨询

PostgreSQL 删除表中完全重复行的解决方案

先确认你的表结构和测试数据:

-- Create the table
CREATE TABLE colour (
col1 VARCHAR,
col2 VARCHAR,
col3 VARCHAR
);

-- Insert sample data
INSERT INTO colour (col1, col2, col3) VALUES
('red', 'blue', 'black'),
('grey', 'red', 'white'),
('pink', NULL, 'blue'),
('red', 'blue', 'black'),
('grey', 'red', 'white'),
('pink', NULL, 'blue');

针对删除完全重复行、仅保留每组一行的需求,提供两种可行方案:

方案一:使用窗口函数精准删除重复行

适合需要保留特定行(比如最早插入的,若有主键可调整排序规则)的场景,同时处理NULL值的比较问题:

WITH duplicate_rows AS (
    SELECT 
        col1, col2, col3,
        ROW_NUMBER() OVER (
            PARTITION BY col1, col2, col3 
            ORDER BY (SELECT NULL) -- 无需指定排序时用此,若有主键可替换为主键字段(如id ASC)
        ) AS rn
    FROM colour
)
DELETE FROM colour
USING duplicate_rows
WHERE 
    (colour.col1, colour.col2, colour.col3) IS NOT DISTINCT FROM (duplicate_rows.col1, duplicate_rows.col2, duplicate_rows.col3)
    AND duplicate_rows.rn > 1;

说明:IS NOT DISTINCT FROM会自动处理NULL值的相等判断,避免因NULL = NULL不成立导致的漏删。

方案二:用DISTINCT ON创建去重表替换原表

适合数据量不大的场景,操作更简洁:

-- 创建临时表存储去重后的数据
CREATE TABLE colour_temp AS
SELECT DISTINCT ON (col1, col2, col3) col1, col2, col3
FROM colour
ORDER BY col1, col2, col3; -- 排序字段需与DISTINCT ON的分组字段一致,确保保留固定行

-- 替换原表
DROP TABLE colour;
ALTER TABLE colour_temp RENAME TO colour;

注意:如果原表有主键、索引或约束,需要在新表上重新创建。

关于你之前CTE失败的可能原因

大概率是没处理NULL值的比较逻辑,或者窗口函数的PARTITION BY未正确覆盖所有字段,导致重复行未被正确分组。使用上述方案中的IS NOT DISTINCT FROM可以避免NULL带来的判断问题。

内容的提问来源于stack exchange,提问作者Mattudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 07:48:10