【问题标题】:Is SQL Having clause syntactic sugar?SQL 有子句语法糖吗?
【发布时间】: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 - 是否是最纯粹意义上的糖取决于实现它的特定数据库

标签: sql database dml


【解决方案1】:

是的,HAVING 是“语法糖”,因为它总是可以被子查询或 CTE 替换。我会注意到一些数据库倾向于实现子查询,因此会增加少量的额外开销。 MySQL 扩展了HAVING 在非聚合上下文中的使用。

也就是说,FROM 子句中的逗号比语法糖更糟糕。它们基本上已经过时,在 1990 年代已被正确的 JOIN 语法取代——那是最后一个千年。它们没有那么强大,因为它们不支持外部连接。

因此,您应该努力学习正确、明确、标准、可读的JOIN 语法,而不是担心HAVING

FROM Employee e JOIN
     Department d
     ON e.DepartmentID = d.DepartmentID

您还应该学习限定查询中的所有列引用。

【讨论】:

  • 如果你想要一个左连接或右连接,你是否在 where 表达式中添加了 + ?
  • @Magnus (+) 是 SQL-92 之前的 Oracle 扩展。这在当时是一个突破,但远不如 SQL-92 连接强大。
  • @TheImpaler:甚至 Oracle 也不鼓励使用 (+) 进行外部连接
  • Db2 也将这种“轮子”视为永远不会流行的东西,并计划明年研究这种称为“火”的新事物,认为它可能很热。跨度>
猜你喜欢
  • 1970-01-01
  • 2013-11-28
  • 2019-08-31
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 2022-11-29
  • 2016-03-10
  • 2017-12-22
相关资源
最近更新 更多