如何筛选满足操作B、C失败或未尝试条件的记录ID
解决方案:筛选符合条件的操作记录ID
根据你的需求,我整理了两种可行的SQL查询方案,帮你精准筛选出满足条件的ID。先再明确下问题背景和数据:
操作表数据
| id | Oper. | Success |
|---|---|---|
| 1 | A | TRUE |
| 1 | B | TRUE |
| 1 | C | TRUE |
| 2 | A | TRUE |
| 2 | B | FALSE |
| 2 | C | TRUE |
| 3 | A | TRUE |
| 3 | B | TRUE |
| 3 | C | FALSE |
| 4 | A | TRUE |
| 4 | B | TRUE |
| 5 | A | TRUE |
| 5 | C | TRUE |
| 6 | A | FALSE |
| 7 | A | TRUE |
| 7 | B | FALSE |
| 7 | C | FALSE |
筛选条件
我们需要找出满足以下任意一条的ID:
- 操作B执行失败(
Success=FALSE) - 操作C执行失败(
Success=FALSE) - 操作B未被执行(表中无该ID的B操作行)
- 操作C未被执行(表中无该ID的C操作行)
方案一:分组聚合查询
这种方法通过分组统计每个ID下的操作情况,直接在HAVING子句中判断条件,代码简洁高效:
SELECT id FROM your_table GROUP BY id HAVING -- 检查B或C操作是否失败 (MAX(CASE WHEN "Oper." = 'B' THEN Success END) = FALSE OR MAX(CASE WHEN "Oper." = 'C' THEN Success END) = FALSE) -- 检查B或C是否未被执行 OR COUNT(CASE WHEN "Oper." = 'B' THEN 1 END) = 0 OR COUNT(CASE WHEN "Oper." = 'C' THEN 1 END) = 0;
逻辑解释
GROUP BY id:将数据按ID分组,方便统计每个ID的所有操作MAX(CASE WHEN "Oper." = 'B' THEN Success END):获取该ID下B操作的结果,如果B未执行,这个值会是NULL,只有当B执行且失败时才会等于FALSECOUNT(CASE WHEN "Oper." = 'B' THEN 1 END) = 0:统计该ID下B操作的行数,为0则说明B未被执行
方案二:LEFT JOIN关联查询
这种方法通过将所有ID与B、C操作分别关联,更直观地判断操作的存在性和结果:
-- 先获取所有存在的ID WITH all_ids AS (SELECT DISTINCT id FROM your_table) SELECT ai.id FROM all_ids ai -- 关联B操作记录 LEFT JOIN your_table b ON ai.id = b.id AND b."Oper." = 'B' -- 关联C操作记录 LEFT JOIN your_table c ON ai.id = c.id AND c."Oper." = 'C' WHERE -- B或C操作失败 (b.Success = FALSE OR c.Success = FALSE) -- B未被执行 OR b.id IS NULL -- C未被执行 OR c.id IS NULL;
逻辑解释
all_idsCTE:先提取表中所有唯一的ID,确保不会遗漏任何IDLEFT JOIN:分别关联每个ID的B、C操作记录,如果该ID没有对应操作,关联后的字段会是NULLWHERE子句直接判断:要么B/C失败,要么B/C不存在(对应关联后的ID为NULL)
两种方案执行后,都会得到预期的结果ID:2(B失败)、3(C失败)、4(C未尝试)、5(B未尝试)、6(B&C未尝试)、7(B和C均失败)。
内容的提问来源于stack exchange,提问作者Caner
相关产品推荐
相关产品推荐

