如何在多分组场景下为每个分组选取最早的1条数据?
实现按用户分组并取最早调度时间行的SQL查询
下面提供几种通用的实现方案,适配不同数据库场景:
方法一:窗口函数(推荐,支持PostgreSQL、MySQL 8.0+、SQL Server等)
利用ROW_NUMBER()窗口函数给每个用户分组内的行按调度时间排序,筛选出排序第一的行:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY USER_ID ORDER BY SCHEDULE_TIME ASC) AS row_rank FROM USER_JOBS ) ranked_jobs WHERE row_rank = 1;
- 说明:
PARTITION BY USER_ID按用户ID分组,ORDER BY SCHEDULE_TIME ASC让每个组内最早的时间排在首位;如果同一用户存在多条相同最早调度时间的行,该方法只会返回其中一行,若需保留所有这类行,可将ROW_NUMBER()替换为RANK()。
方法二:分组关联查询
先通过分组得到每个用户的最早调度时间,再关联原表获取完整行数据:
SELECT uj.* FROM USER_JOBS uj JOIN ( SELECT USER_ID, MIN(SCHEDULE_TIME) AS earliest_schedule FROM USER_JOBS GROUP BY USER_ID ) user_earliest ON uj.USER_ID = user_earliest.USER_ID AND uj.SCHEDULE_TIME = user_earliest.earliest_schedule;
- 说明:该方法会返回同一用户下所有调度时间等于最早时间的行,适合需要保留全部符合条件数据的场景。
方法三:子查询匹配(兼容低版本数据库)
如果数据库不支持窗口函数,可以用行级子查询判断当前行是否为该用户的最早时间:
SELECT * FROM USER_JOBS uj WHERE SCHEDULE_TIME = ( SELECT MIN(SCHEDULE_TIME) FROM USER_JOBS WHERE USER_ID = uj.USER_ID );
- 说明:效果与方法二一致,会返回所有符合最早时间的行。
内容的提问来源于stack exchange,提问作者ismarlowe
相关产品推荐
相关产品推荐

