用 MAX(CASE WHEN condition THEN 1 ELSE 0 END) 1 判断分组内是否存在符合条件的行最稳妥避免 EXISTS 在 GROUP BY 中语法错误或逻辑失效兼容性好且语义清晰。GROUP BY 后怎么判断某组里有没有符合条件的行直接用 HAVING 配合聚合函数最稳妥别硬套 EXISTS —— 它没法直接出现在 GROUP BY 查询的 SELECT 或 HAVING 里强行嵌套会报错或语义错乱。常见错误现象ERROR: syntax error at or near EXISTS或者返回结果和预期完全对不上因为子查询没按组关联。EXISTS 子查询必须显式关联到外层分组字段比如 WHERE t2.group_id t1.group_id否则变成全表扫描逻辑失效想查“每组是否含 status done 的记录”用 MAX(CASE WHEN status done THEN 1 ELSE 0 END) 1 比嵌套 EXISTS 更直观、兼容性更好某些数据库如 MySQL 5.7在 HAVING 中不支持子查询PostgreSQL 虽支持但性能差——聚合判别法基本全版本通用用 MAX(CASE WHEN ...) 实现分组内存在性判断这是最常用也最不容易翻车的做法把布尔条件转成数值再用聚合函数“压缩”成单个标志位。使用场景报表中需要标记“该部门是否有逾期订单”“该用户是否下过 VIP 订单”这类是/否指标。写法固定MAX(CASE WHEN emcondition/em THEN 1 ELSE 0 END) AS has_xxx为什么用 MAX 不用 COUNTCOUNT 统计非空行数但 CASE 的 ELSE 0 是值不是 NULL会导致所有组都返回至少 1MAX 能正确区分“有”和“无”注意 NULL 处理如果条件字段本身可能为 NULL如 status IS NULL需单独写分支不能依赖 ELSE 0SELECT dept_id, MAX(CASE WHEN status overdue THEN 1 ELSE 0 END) AS has_overdueFROM ordersGROUP BY dept_id;想用 EXISTS 又必须分组时的唯一可行写法只能把 EXISTS 放进子查询让外层按组驱动它——本质是“先分组再对每组跑一次 EXISTS”性能敏感场景慎用。 VWO 一个A/B测试工具