SQL实现:按zone_id和subzone_id分组保留operation=0最近出现后的行
在SQL中如何仅保留特定值所在行之后的行?
需求说明
按zone_id和subzone_id分组,仅保留每组内最近一次operation值为0之后的行。其中recency列表示数据新旧程度:值越小越新,值越大越旧,“之后”指记录序列中该0值行之后的更旧数据。
示例数据集
| zone_id | subzone_id | recency | operation |
|---|---|---|---|
| p01 | 1 | 0 | 1 |
| p01 | 1 | 1 | 2 |
| p01 | 1 | 2 | 1 |
| p01 | 1 | 3 | 0 |
| p01 | 1 | 4 | 1 |
| p01 | 1 | 5 | 0 |
| p01 | 1 | 6 | 1 |
| p01 | 1 | 7 | 1 |
| p02 | 1 | 0 | 1 |
| p02 | 2 | 0 | 0 |
| p02 | 2 | 1 | 1 |
期望结果
| zone_id | subzone_id | recency | operation |
|---|---|---|---|
| p01 | 1 | 6 | 1 |
| p01 | 1 | 7 | 1 |
| p02 | 1 | 0 | 1 |
| p02 | 2 | 1 | 1 |
解决方案
使用窗口函数标记每组内最后一次出现operation=0的recency值,再筛选出该值之后的行:
WITH grouped_data AS ( SELECT *, -- 计算每组内最后一次operation=0的recency,无0则设为-1 MAX(CASE WHEN operation = 0 THEN recency ELSE -1 END) OVER (PARTITION BY zone_id, subzone_id) AS last_zero_recency FROM your_table ) SELECT zone_id, subzone_id, recency, operation FROM grouped_data -- 保留recency大于最后一次0值行的recency的记录 WHERE recency > last_zero_recency;
逻辑解释
- 标记最后一次0值行:通过
CASE语句将非0操作的recency转为-1,再用MAX()窗口函数在每组内取最大值,得到该组中最后一次(recency最大,即最旧的)0值行的recency;若组内无0值行,最大值为-1。 - 筛选目标行:保留
recency大于该标记值的行,即为最后一次0值行之后的所有记录。
内容的提问来源于stack exchange,提问作者idiocache
相关产品推荐
相关产品推荐

