MySQL无GROUP BY时HAVING执行顺序及与PostgreSQL差异咨询
MySQL与PostgreSQL中WHERE/HAVING子句的执行逻辑差异
一、MySQL中的执行逻辑
在MySQL中,WHERE子句的执行顺序早于SELECT子句,这意味着WHERE无法引用SELECT中定义的列别名。比如下面的MySQL 5查询会返回「Unknown column」错误:
SELECT id, CASE WHEN LENGTH(TRIM(middle_name)) > 0 THEN CONCAT(first_name, ' ', LEFT (middle_name, 1), '. ', last_name) ELSE CONCAT(first_name, ' ', last_name) END AS name FROM people_table WHERE LENGTH(name) < 11;
但将WHERE替换为HAVING子句后,相同逻辑的查询可以正常运行:
SELECT id, CASE WHEN LENGTH(TRIM(middle_name)) > 0 THEN CONCAT(first_name, ' ', LEFT (middle_name, 1), '. ', last_name) ELSE CONCAT(first_name, ' ', last_name) END AS name FROM people_table HAVING LENGTH(name) < 11;
针对你提出的问题:无GROUP BY子句时,HAVING子句是否在SELECT子句之后执行?
是的,在MySQL中,即使没有GROUP BY子句,HAVING子句也会在SELECT子句之后执行。此时HAVING相当于对SELECT生成的结果集做过滤,因此可以直接引用SELECT中定义的列别名。
二、PostgreSQL中的执行逻辑
PostgreSQL的规则和MySQL有所不同:
- 它不允许在没有
GROUP BY子句的情况下使用HAVING子句; - 但它支持在
WHERE子句中直接引用SELECT定义的列别名,因此下面的查询可以正常运行:
SELECT id, CASE WHEN LENGTH(TRIM(middle_name)) > 0 THEN first_name || ' '|| LEFT(middle_name, 1) || '. '|| last_name ELSE first_name || ' '|| last_name END AS name FROM people_table WHERE LENGTH(name) < 11;
内容的提问来源于stack exchange,提问作者Rushhour Park
相关产品推荐
相关产品推荐

