创建视图基于日期去重:保留最早导入记录的实现方案
问题
我有一张每日追加数据并记录导入日期(Imported)的CLIENTS表,但会产生重复数据。我的目标是基于最早的Imported日期去除重复记录,保留每个姓名组合对应的最早导入记录。
初始表状态
TABLE CLIENTS
| Name | Surname | Imported |
|---|---|---|
| Bob | John | 18-07-2022 |
| Marta | White | 18-07-2022 |
| Ryan | Max | 18-07-2022 |
| Bob | John | 20-07-2022 |
| Marta | White | 20-07-2022 |
| Ryan | Max | 20-07-2022 |
| Brian | Red | 20-07-2022 |
期望结果
| Name | Surname | Imported |
|---|---|---|
| Bob | John | 18-07-2022 |
| Marta | White | 18-07-2022 |
| Ryan | Max | 18-07-2022 |
| Brian | Red | 20-07-2022 |
我原本尝试创建视图筛选出最大Imported日期的记录,代码如下:
CREATE VIEW CLIENTS_VIEW AS SELECT * FROM CLIENTS WHERE "Imported" = ( SELECT MAX("Imported") FROM CLIENTS);
但不清楚如何将该视图与原表匹配,从而保留每个姓名组合对应的最早Imported日期记录。
解决方案
方法1:使用窗口函数ROW_NUMBER()
这是直观且兼容性较好的方案,通过窗口函数按姓名组合分组,对导入日期排序后标记行号,只保留行号为1的记录(即最早导入的那条):
CREATE VIEW CLIENTS_VIEW AS SELECT Name, Surname, Imported FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Name, Surname ORDER BY Imported ASC) AS rn FROM CLIENTS ) t WHERE rn = 1;
PARTITION BY Name, Surname:按姓名组合分组ORDER BY Imported ASC:每组内按导入日期升序排列,最早的记录排在最前- 筛选
rn=1即可得到每组的最早导入记录
方法2:使用GROUP BY子查询关联匹配
先通过GROUP BY获取每个姓名组合的最早导入日期,再和原表关联筛选对应记录:
CREATE VIEW CLIENTS_VIEW AS SELECT c.* FROM CLIENTS c INNER JOIN ( SELECT Name, Surname, MIN(Imported) AS earliest_import FROM CLIENTS GROUP BY Name, Surname ) t ON c.Name = t.Name AND c.Surname = t.Surname AND c.Imported = t.earliest_import;
- 子查询先计算每个姓名组合的最早导入日期
- 通过INNER JOIN匹配原表中姓名和日期都符合的记录,得到目标结果
方法3:直接使用WHERE子查询
如果表中没有唯一主键,也可以用子查询直接筛选:
CREATE VIEW CLIENTS_VIEW AS SELECT * FROM CLIENTS c1 WHERE Imported = ( SELECT MIN(Imported) FROM CLIENTS c2 WHERE c2.Name = c1.Name AND c2.Surname = c1.Surname );
- 对每条记录,查询同姓名组合下的最早导入日期,只保留当前记录日期等于该最早日期的行
内容的提问来源于stack exchange,提问作者Python_Hey
相关产品推荐
相关产品推荐

