Oracle/PLSQL查询需求:筛选各分组中首次将col2改为true的行
Oracle/PLSQL查询需求:筛选各分组中首次将col2改为true的行
嗨,刚接触Oracle/PLSQL不用慌,这个“找出每个col1分组里第一次把col2改成true的行”的需求,其实用两种常见的SQL写法就能轻松实现,我给你详细拆解下:
方法一:分组聚合关联(高效简洁,适合大数据量)
这个思路是先找出每个col1分组里,col2为true的最早变更时间(也就是第一次改成true的时间),再通过这个时间关联回原表拿到完整行数据。
SELECT t1.col1, t1.col2, t1.col3 FROM Table1 t1 INNER JOIN ( -- 子查询:按col1分组,找出每个组内col2为true的最小时间 SELECT col1, MIN(col3) AS first_true_date FROM Table1 WHERE col2 = 'true' -- 如果col2是布尔类型,直接写TRUE即可 GROUP BY col1 ) t2 ON t1.col1 = t2.col1 AND t1.col3 = t2.first_true_date;
针对你的示例数据,子查询会返回:
| col1 | first_true_date |
|---|---|
| 1 | 2022-12-06 |
| 2 | 2018-05-01 |
关联原表后就能精准拿到你需要的第二行和第四行。
方法二:窗口函数标记(灵活应对复杂场景)
如果你的业务场景更复杂(比如同一时间有多个true行、需要观察变更序列等),可以用窗口函数给每行标记序号和累计的true次数,再筛选出第一次出现true的行。
WITH ranked_rows AS ( SELECT col1, col2, col3, -- 按col1分组,按变更时间升序给每行编号 ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col3 ASC) AS row_num, -- 累计当前行及之前所有行中true的数量 SUM(CASE WHEN col2 = 'true' THEN 1 ELSE 0 END) OVER ( PARTITION BY col1 ORDER BY col3 ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS true_count FROM Table1 ) -- 筛选累计true次数为1且当前行是true的记录(也就是第一次出现true的行) SELECT col1, col2, col3 FROM ranked_rows WHERE true_count = 1 AND col2 = 'true';
这个方法的优势是能清晰看到每个分组的变更序列,方便后续扩展其他需求(比如找出第一次从false变true的前后行)。
备注:内容来源于stack exchange,提问作者Farrukh Nabiyev
相关产品推荐
相关产品推荐

