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

PostgreSQL多列识别重复数据并按type字段删除指定行

问题:识别重复数据并删除指定类型行

需求

基于id、datetimestamp、status1、status2四列识别重复项,当同一分组下同时存在type='AR'和type='AN'的行时,删除type='AR'的行,保留type='AN'的行。

样本数据

idtypecycledatetimestampstatus1status2说明
27AN1232022-12-28 04:12:31Normal ANormal A保留
27AR1242022-12-28 04:12:31Normal ANormal A需要删除
19AN1252022-12-28 05:24:30Normal ANormal A保留
19AR1262022-12-28 06:18:20Normal ANormal A保留(无对应AN同分组)
19AR2342022-12-28 07:22:20Normal ANormal A需要删除
19AN2352022-12-28 07:22:20Normal ANormal A保留
20AR2362022-12-28 08:25:49Normal ANormal A需要删除
20AN2372022-12-28 08:25:49Normal ANormal A保留
19AR1292022-12-28 09:08:19Normal ANormal A需要删除
19AN1272022-12-28 09:08:19Normal ANormal A保留
19AR2382022-12-28 10:04:31Normal ANormal A需要删除
19AN2302022-12-28 10:04:31Normal ANormal A保留
22AN2392022-12-28 11:04:58Normal ANormal A保留
22AR2562022-12-28 11:04:58Normal ANormal A需要删除

期望输出

idtypecycledatetimestampstatus1status2
27AN1232022-12-28 04:12:31Normal ANormal A
19AN1252022-12-28 05:24:30Normal ANormal A
19AR1262022-12-28 06:18:20Normal ANormal A
19AN2352022-12-28 07:22:20Normal ANormal A
20AN2372022-12-28 08:25:49Normal ANormal A
19AN1272022-12-28 09:08:19Normal ANormal A
19AN2302022-12-28 10:04:31Normal ANormal A
22AN2392022-12-28 11:04:58Normal ANormal A

原查询问题

原查询语句返回的是type='AN'的行,而非需要删除的type='AR'行,语句如下:

select * from test_data e
where exists
 ( select * from test_data e2 
   where e.datetimestamp=e2.datetimestamp and e.id=e2.id 
     and e.status1=e2.status1 
     and e.status2=e2.status2 
     and e.type='AN' and e2.type='AR') order by e.datetimestamp asc;

问题原因:原查询将e.type='AN'作为外层筛选条件,导致仅返回符合条件的AN行,而非需要删除的AR行。

解决方案

1. 先查询需要删除的AR行(验证用)

SELECT *
FROM test_data e
WHERE e.type = 'AR'
AND EXISTS (
    SELECT 1
    FROM test_data e2
    WHERE e.id = e2.id
      AND e.datetimestamp = e2.datetimestamp
      AND e.status1 = e2.status1
      AND e.status2 = e2.status2
      AND e2.type = 'AN'
)
ORDER BY e.datetimestamp ASC;

2. 删除指定AR行

方式一:使用EXISTS子句

DELETE FROM test_data e
WHERE e.type = 'AR'
AND EXISTS (
    SELECT 1
    FROM test_data e2
    WHERE e.id = e2.id
      AND e.datetimestamp = e2.datetimestamp
      AND e.status1 = e2.status1
      AND e.status2 = e2.status2
      AND e2.type = 'AN'
);

方式二:使用USING子句(PostgreSQL专属)

DELETE FROM test_data e
USING test_data e2
WHERE e.type = 'AR'
  AND e2.type = 'AN'
  AND e.id = e2.id
  AND e.datetimestamp = e2.datetimestamp
  AND e.status1 = e2.status1
  AND e.status2 = e2.status2;

建表及插入数据SQL

CREATE TABLE test_data (
 id character varying(2) NOT NULL,
 type character varying(2),
 cycle integer,
 datetimestamp timestamp without time zone NOT NULL,
 status1 character varying(10),
 status2 character varying(10),
 PRIMARY KEY(id, cycle, datetimestamp)
);

INSERT INTO test_data VALUES
  (27, 'AN', 123, '2022-12-28 04:12:31', 'Normal A', 'Normal A')
, (27, 'AR', 124, '2022-12-28 04:12:31', 'Normal A', 'Normal A')
, (19, 'AN', 125, '2022-12-28 05:24:30', 'Normal A', 'Normal A')
, (19, 'AR', 126, '2022-12-28 06:18:20', 'Normal A', 'Normal A')
, (19, 'AR', 234, '2022-12-28 07:22:20', 'Normal A', 'Normal A')
, (19, 'AN', 235, '2022-12-28 07:22:20', 'Normal A', 'Normal A')
, (20, 'AR', 236, '2022-12-28 08:25:49', 'Normal A', 'Normal A')
, (20, 'AN', 237, '2022-12-28 08:25:49', 'Normal A', 'Normal A')
, (19, 'AR', 129, '2022-12-28 09:08:19', 'Normal A', 'Normal A')
, (19, 'AN', 127, '2022-12-28 09:08:19', 'Normal A', 'Normal A')
, (19, 'AR', 238, '2022-12-28 10:04:31', 'Normal A', 'Normal A')
, (19, 'AN', 230, '2022-12-28 10:04:31', 'Normal A', 'Normal A')
, (22, 'AN', 239, '2022-12-28 11:04:58', 'Normal A', 'Normal A')
, (22, 'AR', 256, '2022-12-28 11:04:58', 'Normal A', 'Normal A')
;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:40:38