求删除重复记录保留最新条目的SQL语句及报错解决(基于valid_until)
删除重复记录并保留最新条目的SQL解决方案
你之前的SQL语句报错,核心原因是多数关系型数据库(如SQL Server)不支持多列组合直接使用NOT IN语法,这就导致了报错提示里的“非布尔类型表达式出现在条件上下文”问题。
以下是针对不同数据库的可行解决方案:
1. SQL Server 适用方案
使用CTE结合窗口函数ROW_NUMBER()标记每条记录的排序,保留每组最新的条目:
WITH RankedRecords AS ( SELECT id, valid_until, -- 按id分组,每组内按valid_until倒序排序,最新的记录标记为1 ROW_NUMBER() OVER (PARTITION BY id ORDER BY valid_until DESC) AS rn FROM tableOne ) -- 删除排序值大于1的重复旧记录 DELETE FROM RankedRecords WHERE rn > 1;
2. MySQL 适用方案
版本8.0及以上(支持窗口函数)
DELETE t1 FROM tableOne t1 JOIN ( SELECT id, valid_until, ROW_NUMBER() OVER (PARTITION BY id ORDER BY valid_until DESC) AS rn FROM tableOne ) t2 ON t1.id = t2.id AND t1.valid_until = t2.valid_until WHERE t2.rn > 1;
低版本MySQL(不支持窗口函数)
DELETE t1 FROM tableOne t1 JOIN tableOne t2 ON t1.id = t2.id AND t1.valid_until < t2.valid_until;
这条语句会删除所有存在同id但valid_until更大的记录,自动保留每个id下日期最新的条目。
3. PostgreSQL 适用方案
PostgreSQL原生支持多列NOT IN,如果你的环境仍报错,可改用窗口函数方案:
DELETE FROM tableOne USING ( SELECT id, valid_until, ROW_NUMBER() OVER (PARTITION BY id ORDER BY valid_until DESC) AS rn FROM tableOne ) ranked WHERE tableOne.id = ranked.id AND tableOne.valid_until = ranked.valid_until AND ranked.rn > 1;
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

