PostgreSQL中如何基于两列组合值删除表内重复记录
PostgreSQL 重复数据删除及唯一约束配置方案
前置操作:备份数据
操作前先对原表进行全量备份,避免误删数据无法恢复:
CREATE TABLE 你的表名_backup AS TABLE 你的表名;
步骤1:确认重复数据范围
先查询Car、Shop字段组合的重复记录,确认待处理数据范围:
SELECT Car, Shop, COUNT(*) AS 重复条数 FROM 你的表名 GROUP BY Car, Shop HAVING COUNT(*) > 1;
原输入表参考:
步骤2:删除重复记录,仅保留唯一行
方案A:表存在主键/唯一标识字段(如自增id)
如下示例保留id更大的唯一行,如需保留id更小的行,将a.id < b.id改为a.id > b.id即可:
DELETE FROM 你的表名 a USING 你的表名 b WHERE a.id < b.id AND a.Car = b.Car AND a.Shop = b.Shop;
方案B:表无主键/唯一标识字段
使用PostgreSQL内置系统字段ctid(每行的物理位置标识,全局唯一)实现去重,默认保留物理位置更靠后的行:
DELETE FROM 你的表名 a USING 你的表名 b WHERE a.ctid < b.ctid AND a.Car = b.Car AND a.Shop = b.Shop;
方案C:窗口函数去重(逻辑更直观)
通过ROW_NUMBER对重复分组编号,删除编号大于1的重复行:
WITH duplicate_rows AS ( SELECT ctid, ROW_NUMBER() OVER( PARTITION BY Car, Shop ORDER BY ctid -- 可自定义排序规则,如按马力、公里数排序 ) AS row_num FROM 你的表名 ) DELETE FROM 你的表名 WHERE ctid IN (SELECT ctid FROM duplicate_rows WHERE row_num > 1);
去重后预期结果参考:
步骤3:添加唯一约束,避免后续产生重复数据
方式1:添加唯一约束
ALTER TABLE 你的表名 ADD CONSTRAINT unique_car_shop UNIQUE (Car, Shop);
方式2:创建唯一索引
CREATE UNIQUE INDEX idx_car_shop_unique ON 你的表名 (Car, Shop);
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

