Oracle SQL:如何选取指定状态最新连续区间的最早记录
Oracle SQL 获取最新连续状态区间的最早记录
针对你的需求,我们可以通过窗口函数分组连续状态区间的方式实现,以下是两种可行的方案:
方案一:利用日期与行号差值分组
这种方法基于连续日期的特性:同一个连续状态区间内,SYM_RUN_DATE 减去按日期排序的行号结果保持一致,以此作为分组标识。
SELECT MIN(SYM_RUN_DATE) AS SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS FROM ( SELECT SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS, -- 生成连续状态区间的分组ID SYM_RUN_DATE - ROW_NUMBER() OVER (PARTITION BY CLIENT_NO, CLIENT_STATUS ORDER BY SYM_RUN_DATE) AS group_id FROM 表A WHERE CLIENT_STATUS = 2 ) t GROUP BY CLIENT_NO, CLIENT_STATUS, group_id -- 筛选包含最新日期的状态区间 HAVING MAX(SYM_RUN_DATE) = ( SELECT MAX(SYM_RUN_DATE) FROM 表A WHERE CLIENT_STATUS = 2 AND CLIENT_NO = t.CLIENT_NO );
方案二:通过状态变化标记分组
先标记状态发生变化的位置,再累加变化标记得到分组ID,最终筛选最新的状态区间。
WITH status_changes AS ( SELECT SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS, -- 标记状态是否发生变化:与上一条记录状态不同则记为1 CASE WHEN LAG(CLIENT_STATUS) OVER (PARTITION BY CLIENT_NO ORDER BY SYM_RUN_DATE) = CLIENT_STATUS THEN 0 ELSE 1 END AS change_flag FROM 表A ), grouped_data AS ( SELECT SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS, -- 累加变化标记生成分组ID SUM(change_flag) OVER (PARTITION BY CLIENT_NO ORDER BY SYM_RUN_DATE) AS group_id FROM status_changes WHERE CLIENT_STATUS = 2 ) SELECT MIN(SYM_RUN_DATE) AS SYM_RUN_DATE, CLIENT_NO, CLIENT_STATUS FROM grouped_data GROUP BY CLIENT_NO, CLIENT_STATUS, group_id -- 按区间的最新日期倒序,取第一个区间 ORDER BY MAX(SYM_RUN_DATE) DESC FETCH FIRST 1 ROW ONLY;
逻辑说明
- 两种方案核心都是先将连续相同的
CLIENT_STATUS=2记录划分为独立区间; - 找到包含最新日期的那个区间;
- 提取该区间的最小日期,即为你需要的结果。
内容的提问来源于stack exchange,提问作者john224
相关产品推荐
相关产品推荐

