SQL Server中如何删除非最早时间数据,仅保留最早记录?
保留SQL Server表中每条记录最早时间数据的删除方案
需求说明
我有一个SQL Server数据表,已经整理好数据,想要删除非最早时间的历史数据,只保留每个(Id_student, name)组合对应的最早时间记录。
我的尝试
先写了这条SELECT查询:
SELECT table1.id, table1.name,MIN(time) FROM table1 GROUP BY id, name,time
但执行下面的DELETE语句时失败了:
DELETE FROM table1 WHERE table1.date EXCEPT MIN(time)
原表数据
| Id_student | name | date |
|---|---|---|
| 1 | azhar | 06:19:20 |
| 1 | azhar | 06:30:30 |
| 1 | azhar | 06:39:30 |
| 1 | azhar | 06:40:30 |
| 1 | azhar | 06:49:30 |
期望结果
| Id_student | name | date |
|---|---|---|
| 1 | azhar | 06:19:20 |
正确解决方法
方法一:子查询匹配保留项
先通过子查询找出每个(Id_student, name)对应的最早date,再删除不在这个匹配范围内的数据:
DELETE FROM table1 WHERE NOT EXISTS ( SELECT 1 FROM ( SELECT Id_student, name, MIN(date) AS min_date FROM table1 GROUP BY Id_student, name ) AS t WHERE t.Id_student = table1.Id_student AND t.name = table1.name AND t.min_date = table1.date )
方法二:CTE+窗口函数(推荐)
用ROW_NUMBER()窗口函数给每个(Id_student, name)分组内的记录按date升序编号,编号大于1的就是需要删除的非最早记录:
WITH RankedData AS ( SELECT Id_student, name, date, ROW_NUMBER() OVER (PARTITION BY Id_student, name ORDER BY date ASC) AS rn FROM table1 ) DELETE FROM RankedData WHERE rn > 1;
问题分析
- 你之前的SELECT查询错误:
GROUP BY里包含了date(你写的是time),这会把每个不同时间的记录单独分组,根本得不到每个用户的最早时间,正确的分组应该只按Id_student和name来做。 - DELETE语句错误:
EXCEPT是集合运算,不能直接用来和聚合函数MIN()做条件对比,必须通过子查询或窗口函数先定位要保留的记录,再删除其余数据。
内容的提问来源于stack exchange,提问作者mycode binary
相关产品推荐
相关产品推荐

