如何在MySQL的WHERE与HAVING条件间使用OR替代默认AND逻辑
MySQL实现WHERE与HAVING条件逻辑为OR的解决方案
SQL执行顺序中WHERE先于GROUP BY、HAVING执行,默认逻辑为「先过滤出满足WHERE所有条件的行,再做聚合运算,最后过滤出满足HAVING所有条件的分组」,二者天然是AND关联,没有直接的语法可以修改关联逻辑,可通过以下方案实现需求:
方案1:子查询标记法(通用性最高)
将原WHERE条件和HAVING条件作为子查询的标记字段,在外层过滤满足任意一个标记的结果即可,示例如下:
SELECT * FROM ( SELECT 分组字段, 聚合函数(字段) AS 聚合别名, -- 标记当前分组是否满足所有原WHERE条件 (原WHERE条件1 AND 原WHERE条件2 AND ...) AS meet_where, -- 标记当前分组是否满足所有原HAVING条件 (原HAVING条件1 AND 原HAVING条件2 AND ...) AS meet_having FROM 表名 GROUP BY 分组字段 ) AS temp_table WHERE meet_where = 1 OR meet_having = 1;
优势:
- 不需要重复编写查询逻辑
- 适配所有业务场景,不管原WHERE条件是否涉及非分组字段
方案2:UNION结果合并法
分别查询满足原WHERE条件的结果、满足原HAVING条件的结果,再合并两个结果集:
-- 结果集1:仅满足所有原WHERE条件的分组 SELECT 分组字段, 聚合函数(字段) AS 聚合别名 FROM 表名 WHERE 原WHERE条件1 AND 原WHERE条件2 AND ... GROUP BY 分组字段 UNION -- 自动去重,允许重复时可替换为UNION ALL提升性能 -- 结果集2:仅满足所有原HAVING条件的分组 SELECT 分组字段, 聚合函数(字段) AS 聚合别名 FROM 表名 GROUP BY 分组字段 HAVING 原HAVING条件1 AND 原HAVING条件2 AND ...;
注意事项:
- 两个查询返回的列数量、列数据类型必须完全一致
- 无需去重时优先用
UNION ALL,执行效率更高
方案3:条件合并到HAVING(仅适配特定场景)
如果原WHERE条件的所有字段都可以通过聚合函数包裹,可直接将所有条件合并到HAVING中用OR关联:
SELECT 分组字段, 聚合函数(字段) AS 聚合别名 FROM 表名 GROUP BY 分组字段 HAVING -- 原WHERE条件用聚合函数包裹后整体作为一个判断 (聚合函数(原WHERE字段1) 条件1 AND 聚合函数(原WHERE字段2) 条件2 AND ...) OR (原HAVING条件1 AND 原HAVING条件2 AND ...);
限制:
仅适用于原WHERE条件可以通过聚合函数转化为分组级判断的场景,比如原WHERE判断的是分组字段的属性,或者可以用MAX/MIN/ANY等聚合函数包裹后逻辑不变的场景。
内容的提问来源于stack exchange,提问作者Rezigdev.com
相关产品推荐
相关产品推荐

