在SSMS中删除MessageID重复且时间戳大于最小值的行
需求说明
我在SSMS中执行以下查询:
SELECT MessageID ,MessageName ,DateTimeStamp FROM faa_source_cleansed.message_meta_data
当前表中数据如下:
| MessageID | MessageName | DateTimeStamp |
|---|---|---|
| MS_2srpuI0UBZC0yMe | Proxy_TEST | 2023-02-06 14:10:16.570 |
| MS_2srpuI0UBZC0yMe | Proxy_TEST | 2023-02-06 14:17:40.517 |
| MS_3DIRR1wBVXPrdlQ | Proxy_TEST | 2023-02-06 14:17:40.517 |
| MS_2srpuI0UBZC0yMe | Proxy_TEST | 2023-02-06 14:29:55.527 |
| MS_3DIRR1wBVXPrdlQ | Proxy_TEST | 2023-02-06 14:29:55.527 |
| MS_dpbKrzgBsXgVpTE | Proxy_TEST | 2023-02-06 14:29:55.527 |
需要删除每个MessageID对应的时间戳大于其最小时间戳的行,最终保留每个MessageID最早的记录,期望结果如下:
| MessageID | MessageName | DateTimeStamp |
|---|---|---|
| MS_2srpuI0UBZC0yMe | Proxy_TEST | 2023-02-06 14:10:16.570 |
| MS_3DIRR1wBVXPrdlQ | Proxy_TEST | 2023-02-06 14:17:40.517 |
| MS_dpbKrzgBsXgVpTE | Proxy_TEST | 2023-02-06 14:29:55.527 |
解决方案
以下几种方法均可实现需求:
方法1:CTE结合ROW_NUMBER()函数
通过CTE为每个MessageID的记录按时间戳升序排序,标记出最早的条目,再删除标记不为1的行:
WITH RankedMessages AS ( SELECT MessageID, MessageName, DateTimeStamp, ROW_NUMBER() OVER (PARTITION BY MessageID ORDER BY DateTimeStamp ASC) AS rn FROM faa_source_cleansed.message_meta_data ) DELETE FROM RankedMessages WHERE rn > 1;
方法2:子查询匹配最小时间戳
直接通过子查询获取每个MessageID的最小时间戳,删除时间戳大于该值的行:
DELETE FROM faa_source_cleansed.message_meta_data WHERE DateTimeStamp > ( SELECT MIN(DateTimeStamp) FROM faa_source_cleansed.message_meta_data AS t2 WHERE t2.MessageID = faa_source_cleansed.message_meta_data.MessageID );
方法3:JOIN方式删除
先分组查询每个MessageID的最小时间戳,再通过JOIN匹配并删除不符合条件的行:
DELETE t1 FROM faa_source_cleansed.message_meta_data t1 JOIN ( SELECT MessageID, MIN(DateTimeStamp) AS MinDateTime FROM faa_source_cleansed.message_meta_data GROUP BY MessageID ) t2 ON t1.MessageID = t2.MessageID WHERE t1.DateTimeStamp > t2.MinDateTime;
结果验证
执行删除操作后,重新运行原始查询即可得到期望的结果。
内容的提问来源于stack exchange,提问作者Sagar Negi US
相关产品推荐
相关产品推荐

