如何获取指定日期下各ID最新startdate且end date非空的记录
获取指定日期下各ID最新有效记录的SQL实现
需求说明
筛选指定日期范围内,end date不为空的记录,对每个ID仅保留startdate最新的那一条。
原始数据表
| ID | status | startdate | end date |
|---|---|---|---|
| 1 | completed | 2023-03-01 13:12:10 | 2023-03-01 13:15:10 |
| 2 | error | 2023-03-01 13:12:10 | null |
| 3 | completed | 2023-03-01 13:12:10 | 2023-03-01 13:12:10 |
| 1 | completed | 2023-03-01 13:20:10 | 2023-03-01 13:22:10 |
| 2 | completed | 2023-03-01 13:22:10 | 2023-03-01 13:25:10 |
| 2 | completed | 2023-03-01 13:24:10 | 2023-03-01 13:26:10 |
期望输出
| ID | status | startdate | end date |
|---|---|---|---|
| 1 | completed | 2023-03-01 13:20:10 | 2023-03-01 13:22:10 |
| 2 | completed | 2023-03-01 13:24:10 | 2023-03-01 13:26:10 |
| 3 | completed | 2023-03-01 13:12:10 | 2023-03-01 13:12:10 |
解决方案
使用窗口函数ROW_NUMBER()可以精准实现需求,步骤如下:
- 过滤
end date为空的记录,同时限定目标日期 - 按ID分组,每组内按
startdate倒序标记序号 - 仅保留每组序号为1的记录(即最新记录)
通用SQL代码
WITH ranked_records AS ( SELECT ID, status, startdate, `end date`, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY startdate DESC) AS rn FROM your_table_name WHERE `end date` IS NOT NULL AND DATE(startdate) = '2023-03-01' -- 替换为你的目标日期 ) SELECT ID, status, startdate, `end date` FROM ranked_records WHERE rn = 1 ORDER BY ID;
代码细节说明
PARTITION BY ID:确保每个ID单独分组排序ORDER BY startdate DESC:让最新的记录排在组内第一位,序号标记为1DATE(startdate):提取日期部分筛选指定日期的记录,不同数据库语法略有差异:- MySQL:
DATE(startdate) - SQL Server:
CAST(startdate AS DATE) - Oracle:
TRUNC(startdate)
- MySQL:
简化版本(支持QUALIFY子句的数据库)
如果使用BigQuery、Snowflake等支持QUALIFY的数据库,可省略CTE,直接写:
SELECT ID, status, startdate, `end date` FROM your_table_name WHERE `end date` IS NOT NULL AND DATE(startdate) = '2023-03-01' QUALIFY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY startdate DESC) = 1 ORDER BY ID;
内容的提问来源于stack exchange,提问作者gulhasan siddique
相关产品推荐
相关产品推荐

