如何按City分组后,获取每组最早date对应的Person数据?
如何查询每个城市中日期最早的人员?
首先来看你的原始数据:
City date Person A 2018/05/01 peter A 2018/03/01 Jack B 2018/02/16 TOM C 2018/03/01 Mike
你需要提取每个城市里日期最早的人员记录,期望结果如下:
A 2018/03/01 Jack B 2018/02/16 TOM C 2018/03/01 Mike
这是一个典型的分组取最值的SQL需求,下面给你几种通用的实现方式,适配不同的数据库场景:
方法一:使用窗口函数(推荐,适用于现代数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),用ROW_NUMBER()是最清晰直观的方案:
WITH ranked_data AS ( SELECT City, date, Person, -- 按城市分组,组内按日期升序编号 ROW_NUMBER() OVER (PARTITION BY City ORDER BY date ASC) AS row_num FROM your_table_name -- 替换成你的实际表名 ) SELECT City, date, Person FROM ranked_data WHERE row_num = 1;
说明:
PARTITION BY City:把数据按城市拆分成独立的分组ORDER BY date ASC:每个分组内按日期从早到晚排序ROW_NUMBER():给每个分组内的行分配序号,日期最早的行序号为1,最后筛选出序号为1的记录即可
如果同一个城市存在多条日期相同的最早记录,你可以把ROW_NUMBER()换成RANK(),这样会返回所有符合条件的记录,而不是只取一条。
方法二:关联子查询(适配老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用关联子查询来实现:
SELECT t1.City, t1.date, t1.Person FROM your_table_name t1 -- 替换成你的实际表名 WHERE t1.date = ( -- 子查询找出当前城市的最小日期 SELECT MIN(date) FROM your_table_name t2 WHERE t2.City = t1.City );
说明:
子查询会为每一行(t1)找出对应城市的最小日期,然后主查询匹配该城市和最小日期的记录。和RANK()的效果类似,如果有多个相同的最早日期,会返回所有符合的记录。
方法三:GROUP BY + JOIN
另一种思路是先通过GROUP BY得到每个城市的最小日期,再和原表关联匹配出对应的人员信息:
SELECT t1.City, t1.date, t1.Person FROM your_table_name t1 -- 替换成你的实际表名 JOIN ( -- 先分组获取每个城市的最小日期 SELECT City, MIN(date) AS min_date FROM your_table_name GROUP BY City ) t2 ON t1.City = t2.City AND t1.date = t2.min_date;
这个方法的效果和关联子查询一致,同样能返回所有日期最早的记录(如果有重复)。
注意事项:
- 请把SQL中的
your_table_name替换成你实际使用的表名 - 如果你的
date字段是字符串类型,要确保数据库能正确识别并排序(建议将字段类型改为DATE或DATETIME,避免排序错误)
内容的提问来源于stack exchange,提问作者kk luo
相关产品推荐
相关产品推荐

