获取每个用户倒数第二个DEF_ENDING为X后的首个BEG_PERIOD日期
需求与解决方案
需求说明
获取每个USER_ID对应的倒数第二条DEF_ENDING值为X的记录之后的第一条BEG_PERIOD日期。
现有PERIODS表数据
| USER_ID | BEG_PERIOD | END_PERIOD | DEF_ENDING |
|---|---|---|---|
| 159 | 01-07-2022 | 31-07-2022 | X |
| 159 | 25-09-2022 | 15-10-2022 | X |
| 159 | 01-11-2022 | 13-11-2022 | |
| 159 | 14-11-2022 | 21-12-2022 | X |
| 159 | 01-01-2023 | 30-01-2023 | X |
| 414 | 01-04-2022 | 31-05-2022 | X |
| 414 | 01-07-2022 | 30-09-2022 | |
| 414 | 01-10-2022 | 01-12-2022 | X |
| 480 | 01-07-2022 | 30-06-2022 | |
| 480 | 01-07-2022 | 30-08-2022 | X |
| 480 | 02-09-2022 | 01-11-2022 | X |
| 503 | 15-03-2022 | 16-06-2022 | X |
| 503 | 19-07-2022 | 23-07-2022 | |
| 503 | 24-07-2022 | 31-10-2022 | |
| 503 | 01-11-2022 | 21-12-2022 | X |
尝试的SQL(仅能获取最新日期)
SELECT p.USER_ID, p.BEG_PERIOD FROM PERIODS p INNER JOIN PERIODS p2 ON p.USER_ID = p2.USER_ID AND p.BEG_PERIOD = ( SELECT MAX( BEG_PERIOD ) FROM PERIODS WHERE PERIODS.USER_ID = p.USER_ID ) WHERE p.USER_ID > 10
正确解决方案
要实现需求,需要分两步:先定位每个用户的倒数第二条X记录,再找到该记录之后的第一条记录的BEG_PERIOD。以下是基于窗口函数的SQL实现:
WITH all_records AS ( SELECT USER_ID, BEG_PERIOD, END_PERIOD, DEF_ENDING, -- 给每个用户的X记录按时间升序编号 COUNT(CASE WHEN DEF_ENDING = 'X' THEN 1 END) OVER (PARTITION BY USER_ID ORDER BY BEG_PERIOD) AS x_seq, -- 统计每个用户的X记录总数 COUNT(CASE WHEN DEF_ENDING = 'X' THEN 1 END) OVER (PARTITION BY USER_ID) AS total_x FROM PERIODS ), second_last_x AS ( SELECT USER_ID, END_PERIOD AS x_end_date FROM all_records WHERE DEF_ENDING = 'X' AND x_seq = total_x - 1 ) SELECT slx.USER_ID, MIN(p.BEG_PERIOD) AS target_beg_period FROM second_last_x slx JOIN PERIODS p ON slx.USER_ID = p.USER_ID WHERE p.BEG_PERIOD > slx.x_end_date GROUP BY slx.USER_ID;
逻辑说明
all_recordsCTE:给每个用户的所有记录计算两个值:x_seq是该用户截至当前记录的X记录累计数,total_x是该用户的X记录总数量。second_last_xCTE:筛选出每个用户的倒数第二条X记录(即x_seq = total_x - 1的X记录),并保留其结束日期。- 最后关联原表,找到该用户中所有开始日期晚于倒数第二条X记录结束日期的记录,取最小的开始日期即为目标日期。
结果验证
执行上述SQL后,将得到以下结果:
| USER_ID | target_beg_period |
|---|---|
| 159 | 01-01-2023 |
| 414 | 01-07-2022 |
| 480 | 02-09-2022 |
| 503 | 19-07-2022 |
内容的提问来源于stack exchange,提问作者tg_rs
相关产品推荐
相关产品推荐

