【发布时间】:2020-08-12 06:27:17
【问题描述】:
只是好奇 SQL 中的 HAVING 子句是否只是 a syntactic sugar 用于子查询上的 WHERE 子句?
例如:
SELECT DepartmentName, COUNT(*)
FROM Employee, Department
WHERE Employee.DepartmentID = Department.DepartmentID
GROUP BY DepartmentName
HAVING COUNT(*)>1;
等价于
SELECT * FROM (
SELECT DepartmentName AS deptNam, COUNT(*) AS empCnt
FROM Employee AS emp, Department AS dept
WHERE emp.DepartmentID = dept.DepartmentID
GROUP BY deptNam
) AS grp
WHERE grp.empCnt > 1;
这样就可以用子查询+WHERE重写HAVING。
所以唯一的区别是打印字符数 + 数据库供应商细节?
(来自维基百科https://en.wikipedia.org/wiki/Having_(SQL)的示例)
【问题讨论】:
-
HAVING 是核心 ANSI SQL,派生表是 ANSI SQL 扩展(功能 F591)。此外,HAVING 已经存在很长时间了,派生表稍微更新一些。
-
一些廉价数据库的优化器将能够优雅地处理第一个,但可能会遇到第二个问题。他们将无法改写查询。
-
按照这个逻辑,JOIN 或 WHERE 子句也是语法糖?
-
@CaiusJard:我怀疑你可以在没有 WHERE 子句的情况下进行过滤,因此如果没有 HAVING 我想我可以过滤带有子查询的聚合。
-
SELECT p.* FROM person p INNER JOIN (SELECT 'Smith' as LastName FROM DUAL) x ON x.LastName = p.LastName等同于SELECT * FROM person WHERE p.LastName = 'Smith';我的观点主要是,仅仅因为有几种做某事的方法并不一定意味着一种是另一种的语法糖。 HAVING 是在组之后完成的 where 子句。 WHERE 在组之前完成,但WHERE GROUP HAVING肯定会被重写为(WHERE GROUP) WHERE- 是否是最纯粹意义上的糖取决于实现它的特定数据库