如何按分组和日期排序后保留每组最新行删除MySQL其余数据?
实现保留最新记录的存储过程
嘿,我来帮你搞定这个需求!要实现按Application_Id和External_Account_Id分组,仅保留每组中Last_Warning_Message最新的记录,我们可以用窗口函数标记每组内的记录排名,再删除排名靠后的旧记录。下面是针对主流数据库的具体实现方案:
针对SQL Server的存储过程
CREATE PROCEDURE KeepLatestWarningRecords AS BEGIN -- 禁用计数提示,提升执行效率 SET NOCOUNT ON; -- 用CTE给每条记录标记组内排名 WITH RankedRecords AS ( SELECT *, -- 按目标字段分组,最新的记录排名为1 ROW_NUMBER() OVER ( PARTITION BY Application_Id, External_Account_Id ORDER BY Last_Warning_Message DESC ) AS RecordRank FROM YourTableName -- 替换成你的实际表名 ) -- 删除组内非最新的记录(排名>1) DELETE FROM RankedRecords WHERE RecordRank > 1; -- 输出删除统计(可选) PRINT '已删除 ' + CAST(@@ROWCOUNT AS VARCHAR) + ' 条旧记录'; END;
针对MySQL 8.0+的存储过程
DELIMITER // CREATE PROCEDURE KeepLatestWarningRecords() BEGIN DELETE t1 FROM YourTableName t1 JOIN ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY Application_Id, External_Account_Id ORDER BY Last_Warning_Message DESC ) AS RecordRank FROM YourTableName ) t2 ON t1.Id = t2.Id -- 替换成你的表主键字段 WHERE t2.RecordRank > 1; -- 输出删除统计 SELECT CONCAT('已删除 ', ROW_COUNT(), ' 条旧记录') AS 执行结果; END // DELIMITER ;
关键说明
PARTITION BY Application_Id, External_Account_Id:确保我们只在同一Application_Id+External_Account_Id的组内处理记录ORDER BY Last_Warning_Message DESC:让每组中最新的记录排名为1,旧记录排名依次递增- 重要提示:执行前一定要把代码中的
YourTableName和主键字段替换成你实际的表名/字段!
安全测试建议
在执行删除操作前,先运行下面的查询确认要删除的记录,避免误操作:
-- SQL Server/MySQL通用查询 WITH RankedRecords AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY Application_Id, External_Account_Id ORDER BY Last_Warning_Message DESC ) AS RecordRank FROM YourTableName ) SELECT * FROM RankedRecords WHERE RecordRank > 1;
执行完存储过程后,你的数据表就会和预期一样,只保留每组中Last_Warning_Message最新的那条记录啦!
内容的提问来源于stack exchange,提问作者Ibraheem Mansour
相关产品推荐
相关产品推荐

