使用T-SQL按条件删除重复邮箱的非今日数据
正确实现T-SQL删除语句的方案
需求说明
- 筛选出邮箱(Email)相同的数据
- 若同一邮箱的记录同时存在
AllLocations为'Yes'和'No'的情况,删除其中非今日(示例中今日为2025/4/9)的记录
示例数据
原始数据
UserName Email AllLocations Location DateLoad John Doe jdoe@gmail.com No Cerritos 4/9/2025 John Doe jdoe@gmail.com No Cerritos 4/9/2025 John Doe jdoe@gmail.com Yes 2/21/2025 Jane Sue jsue@yahoo.com No Los Angeles 3/31/2025
删除后预期结果
UserName Email AllLocations Location DateLoad John Doe jdoe@gmail.com No Cerritos 4/9/2025 John Doe jdoe@gmail.com No Cerritos 4/9/2025 Jane Sue jsue@yahoo.com No Los Angeles 3/31/2025
错误语句问题分析
原语句存在逻辑优先级错误(OR与AND未正确分组),且通过表自关联的方式会误匹配并删除不符合要求的行,无法精准定位需要删除的目标记录。
正确实现方案
方案一:使用CTE+窗口函数(推荐)
通过窗口函数按邮箱分组,统计该邮箱下AllLocations的状态种类,再筛选出需要删除的行:
WITH EmailStatus AS ( SELECT *, -- 统计当前邮箱下有多少种不同的AllLocations状态 COUNT(DISTINCT AllLocations) OVER (PARTITION BY Email) AS StatusTypeCount, -- 标记当前行是否为今日记录 CASE WHEN CAST(DateLoad AS DATE) = CAST(GETDATE() AS DATE) THEN 1 ELSE 0 END AS IsTodayRecord FROM [table] ) DELETE FROM EmailStatus WHERE StatusTypeCount = 2 -- 邮箱同时存在Yes和No两种状态 AND IsTodayRecord = 0; -- 非今日记录
如果需要固定日期(如示例中的2025/4/9),将CAST(GETDATE() AS DATE)替换为'2025-04-09'即可。
方案二:使用EXISTS关联判断
通过两次EXISTS检查,判断当前邮箱是否同时存在Yes和No的记录,再删除非今日行:
DELETE t1 FROM [table] t1 WHERE -- 当前行不是今日记录 CAST(t1.DateLoad AS DATE) != CAST(GETDATE() AS DATE) -- 当前邮箱存在AllLocations为Yes的记录 AND EXISTS ( SELECT 1 FROM [table] t2 WHERE t2.Email = t1.Email AND t2.AllLocations = 'Yes' ) -- 当前邮箱存在AllLocations为No的记录 AND EXISTS ( SELECT 1 FROM [table] t2 WHERE t2.Email = t1.Email AND t2.AllLocations = 'No' );
内容的提问来源于stack exchange,提问作者Java
相关产品推荐
相关产品推荐

