按ID分组的Status筛选问题:CASE语句未按ID维度处理求助
按ID维度筛选状态记录的解决方案
我明白你的问题了——原来的CASE语句是单条记录层面的判断,根本没考虑同一个ID下的其他状态,所以没法实现你要的按ID维度筛选逻辑。我们得先按ID聚合,判断该ID包含的所有状态类型,再根据这个结果来处理记录,下面给你两种实用的方案:
方案1:直接筛选出每个ID符合要求的记录
如果你的需求是每个ID只保留一条符合规则的记录(即只要ID存在Approved状态,不管有没有Later/Modified,都保留Approved这条记录),可以用子查询先统计每个ID的状态情况,再关联筛选:
WITH id_status_stats AS ( SELECT ID, -- 标记该ID是否有Approved状态 MAX(CASE WHEN Status = 'Approved' THEN 1 ELSE 0 END) AS has_approved, -- 标记该ID是否有Later或Modified状态 MAX(CASE WHEN Status IN ('Later', 'Modified') THEN 1 ELSE 0 END) AS has_other FROM your_table GROUP BY ID ) SELECT t.ID, t.Status FROM your_table t JOIN id_status_stats s ON t.ID = s.ID -- 核心筛选逻辑:只要ID有Approved,就保留Approved记录 WHERE s.has_approved = 1 AND t.Status = 'Approved' -- 如果需要处理没有Approved的ID,可以补充OR条件,比如: -- OR (s.has_approved = 0 AND t.Status = [你的默认处理状态])
方案2:给每条记录标记最终状态(保留所有记录)
如果需要保留所有原始记录,但给每个ID的记录标记符合规则的最终状态(比如只要ID有Approved,最终状态就统一为Approved;如果只有Approved,也保持Approved),可以用窗口函数实现行级关联ID的全局状态:
SELECT ID, Status, CASE -- 只要当前ID存在Approved,最终状态就设为Approved WHEN MAX(CASE WHEN Status = 'Approved' THEN 1 ELSE 0 END) OVER (PARTITION BY ID) = 1 THEN 'Approved' -- 没有Approved的ID,保留原状态(可根据需求调整) ELSE Status END AS Final_Status FROM your_table
额外调整:如果需要标记"Partial Modified"
看你原来的CASE语句里提到了Partial Modified,如果你的需求是:当ID同时存在Approved和Later/Modified时,把Approved记录标记为Partial Modified,只有当ID仅存在Approved时才保留Approved,那可以修改方案2的CASE逻辑:
SELECT ID, Status, CASE -- ID同时有Approved和其他状态时,Approved标记为Partial Modified WHEN Status = 'Approved' AND MAX(CASE WHEN Status IN ('Later', 'Modified') THEN 1 ELSE 0 END) OVER (PARTITION BY ID) = 1 THEN 'Partial Modified' -- ID只有Approved时,保留Approved WHEN Status = 'Approved' THEN 'Approved' -- 其他状态的记录可按需保留或过滤 ELSE Status END AS Final_Status FROM your_table
内容的提问来源于stack exchange,提问作者user1046415
相关产品推荐
相关产品推荐

