如何在MySQL中找出重复条目并保留最大Expiration值条目删除其余
按ID分组保留Expiration最大值记录的解决方案
针对你的需求——按ID分组,仅保留每组中Expiration值最高的记录、删除其余重复条目,以下是不同数据库环境下的实现方法:
MySQL 实现方式
方法1:自连接删除
通过自连接匹配同一ID的记录,直接删除Expiration值较小的条目:
DELETE t1 FROM your_table t1 JOIN your_table t2 ON t1.ID = t2.ID WHERE t1.Expiration < t2.Expiration;
该语句会逐步清理同一ID下非最大值的记录,最终仅保留每组的Expiration最大值条目。
方法2:子查询匹配删除
先通过子查询获取每个ID对应的最大Expiration值,再删除不在这个匹配集合内的记录:
DELETE FROM your_table WHERE (ID, Expiration) NOT IN ( SELECT ID, MAX(Expiration) FROM your_table GROUP BY ID );
如果表存在主键,这种方法更稳妥;若没有主键,需确保不存在ID和Expiration完全重复的记录。
PostgreSQL 实现方式
使用窗口函数给每条记录排名,再删除排名大于1的条目:
WITH ranked_records AS ( SELECT ID, Expiration, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Expiration DESC) AS rn FROM your_table ) DELETE FROM your_table WHERE (ID, Expiration) IN ( SELECT ID, Expiration FROM ranked_records WHERE rn > 1 );
ROW_NUMBER()会按ID分组,给Expiration降序的记录标记排名,排名>1的即为需要删除的非最大值条目。
SQL Server 实现方式
同样借助窗口函数,支持直接删除CTE中的目标记录:
WITH ranked_records AS ( SELECT ID, Expiration, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Expiration DESC) AS rn FROM your_table ) DELETE FROM ranked_records WHERE rn > 1;
注意事项
- 执行删除操作前务必备份数据,防止误删导致数据丢失。
- 若同一ID下存在多条Expiration值相同的最大值记录,上述方法中使用
ROW_NUMBER()会随机保留一条;若要保留所有最大值记录,可替换为RANK()或DENSE_RANK()函数。 - 表中存在其他字段时,这些方法依然适用,核心逻辑是通过ID和Expiration匹配目标记录。
内容的提问来源于stack exchange,提问作者Ace
相关产品推荐
相关产品推荐

