如何针对最小日期行的条件返回最大日期结果?
针对最小日期行条件返回最大日期结果的SQL方案
看起来你需要针对每个作业(ID),先定位它最早日期对应的步骤,然后输出该作业里最晚日期的步骤及日期数据对吧?结合你的样例数据和基础查询,我给你两种可行的实现方案:
先看你的样例数据:
| ID | step | date |
|---|---|---|
| 1 | SECOND_ATTEMPT | 03/19/2018 |
| 1 | QC_READY | 03/23/2018 |
| 1 | QC_REJECTS | 03/26/2018 |
| 2 | SCHEDULED | 02/01/2018 |
| 2 | FINISHED | 02/04/2018 |
| 3 | SECOND_ATTEMPT | 04/02/2018 |
| 3 | QC_READY | 04/03/2018 |
| 4 | SECOND_ATTEMPT | 01/15/2018 |
| 4 | FINISHED | 01/25/2018 |
方案1:窗口函数(推荐,简洁高效)
如果你的数据库支持窗口函数(比如PostgreSQL、MySQL 8+、SQL Server等),这是最优解。我们可以用窗口函数一次性计算每个ID的最小和最大日期,再筛选出需要的记录:
WITH job_date_metrics AS ( SELECT j.id, wfh.step, wfh.date, -- 计算每个ID的最早日期 MIN(wfh.date) OVER (PARTITION BY j.id) AS earliest_job_date, -- 计算每个ID的最晚日期 MAX(wfh.date) OVER (PARTITION BY j.id) AS latest_job_date FROM Job j JOIN work_flow_history wfh ON j.id = wfh.job_id ) SELECT id, step AS latest_step, date AS latest_date FROM job_date_metrics -- 筛选出当前ID的最晚日期记录 WHERE date = latest_job_date -- 如果你需要只保留"最早步骤是特定值"的作业(比如最早步骤是SECOND_ATTEMPT),可以打开下面的注释: -- AND EXISTS ( -- SELECT 1 -- FROM job_date_metrics jdm -- WHERE jdm.id = job_date_metrics.id -- AND jdm.date = jdm.earliest_job_date -- AND jdm.step = 'SECOND_ATTEMPT' -- )
方案2:子查询关联(兼容老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用子查询先获取每个ID的日期极值,再关联原表得到结果:
SELECT j.id, wfh_latest.step AS latest_step, wfh_latest.date AS latest_date FROM Job j -- 关联获取每个ID的最晚日期记录 JOIN work_flow_history wfh_latest ON j.id = wfh_latest.job_id JOIN ( -- 先算出每个ID的最晚日期 SELECT job_id, MAX(date) AS latest_date FROM work_flow_history GROUP BY job_id ) date_max ON wfh_latest.job_id = date_max.job_id AND wfh_latest.date = date_max.latest_date -- 同样,如果需要筛选最早步骤满足条件的作业,加入下面的关联和条件: -- JOIN ( -- -- 获取每个ID最早日期对应的步骤 -- SELECT job_id, step -- FROM work_flow_history wfh_earliest -- WHERE date = (SELECT MIN(date) FROM work_flow_history WHERE job_id = wfh_earliest.job_id) -- ) step_earliest ON j.id = step_earliest.job_id -- -- 这里指定最早步骤的条件,比如只保留SECOND_ATTEMPT -- WHERE step_earliest.step = 'SECOND_ATTEMPT'
结果展示
针对你的样例数据,运行不带筛选条件的查询,输出会是:
| id | latest_step | latest_date |
|---|---|---|
| 1 | QC_REJECTS | 03/26/2018 |
| 2 | FINISHED | 02/04/2018 |
| 3 | QC_READY | 04/03/2018 |
| 4 | FINISHED | 01/25/2018 |
如果打开筛选条件(只保留最早步骤为SECOND_ATTEMPT的作业),输出会是:
| id | latest_step | latest_date |
|---|---|---|
| 1 | QC_REJECTS | 03/26/2018 |
| 3 | QC_READY | 04/03/2018 |
| 4 | FINISHED | 01/25/2018 |
内容的提问来源于stack exchange,提问作者juppys
相关产品推荐
相关产品推荐

