SQL删除数据需求咨询:保留Kubun1最小时间、Kubun2最大时间的方案求助
解决方案
前置说明
按 Kubun、Name、Code、Date 四个字段分组处理,每个分组内的保留规则如下:
- Kubun为1的分组:仅保留Time字段最小的记录
- Kubun为2的分组:仅保留Time字段最大的记录
步骤1:先验证要保留的记录(必做,避免误删数据)
运行以下查询,核对输出的4条记录是否符合预期:
SELECT t.* FROM 表1 t INNER JOIN ( SELECT Kubun, Name, Code, Date, CASE WHEN Kubun = 1 THEN MIN(Time) WHEN Kubun = 2 THEN MAX(Time) END AS target_time FROM 表1 GROUP BY Kubun, Name, Code, Date ) keep_record ON t.Kubun = keep_record.Kubun AND t.Name = keep_record.Name AND t.Code = keep_record.Code AND t.Date = keep_record.Date AND t.Time = keep_record.target_time
步骤2:执行删除操作
根据你使用的数据库选择对应写法:
写法1:通用兼容写法(支持所有主流数据库,包括低版本MySQL、Access等)
DELETE FROM 表1 t WHERE NOT EXISTS ( SELECT 1 FROM ( SELECT Kubun, Name, Code, Date, CASE WHEN Kubun = 1 THEN MIN(Time) WHEN Kubun = 2 THEN MAX(Time) END AS target_time FROM 表1 GROUP BY Kubun, Name, Code, Date ) keep_record WHERE t.Kubun = keep_record.Kubun AND t.Name = keep_record.Name AND t.Code = keep_record.Code AND t.Date = keep_record.Date AND t.Time = keep_record.target_time )
写法2:窗口函数写法(支持MySQL8.0+、SQL Server、PostgreSQL等新数据库,更简洁)
先验证标记是否正确:
SELECT *, ROW_NUMBER() OVER( PARTITION BY Kubun, Name, Code, Date ORDER BY CASE WHEN Kubun = 1 THEN Time END ASC, CASE WHEN Kubun = 2 THEN Time END DESC ) AS rn FROM 表1
查询结果中rn=1的就是要保留的记录,确认无误后执行删除:
WITH temp AS ( SELECT *, ROW_NUMBER() OVER( PARTITION BY Kubun, Name, Code, Date ORDER BY CASE WHEN Kubun = 1 THEN Time END ASC, CASE WHEN Kubun = 2 THEN Time END DESC ) AS rn FROM 表1 ) DELETE FROM temp WHERE rn > 1
特殊场景处理(Access等不支持嵌套删除的数据库)
可以用临时表中转的方式实现:
-- 1. 将需要保留的记录存入临时表 SELECT t.* INTO 表1_临时保留 FROM 表1 t INNER JOIN ( SELECT Kubun, Name, Code, Date, CASE WHEN Kubun = 1 THEN MIN(Time) WHEN Kubun = 2 THEN MAX(Time) END AS target_time FROM 表1 GROUP BY Kubun, Name, Code, Date ) keep_record ON t.Kubun = keep_record.Kubun AND t.Name = keep_record.Name AND t.Code = keep_record.Code AND t.Date = keep_record.Date AND t.Time = keep_record.target_time -- 2. 清空原表 DELETE FROM 表1 -- 3. 将保留的记录插回原表 INSERT INTO 表1 SELECT * FROM 表1_临时保留 -- 4. 确认无误后删除临时表 DROP TABLE 表1_临时保留
注意事项
执行删除操作前务必提前备份全量数据,先在测试环境验证逻辑正确后再在生产环境执行。
内容的提问来源于stack exchange,提问作者Andre Thang
相关产品推荐
相关产品推荐

