【发布时间】:2022-01-08 08:36:00
【问题描述】:
当我使用GROUP BY 而不是WHERE 子句时,我学会了使用HAVING,并且从未遇到任何问题。今天我在 w3schools.com 的一个 SQL 学习页面上看到了这个:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders
FROM Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
WHERE LastName = 'Davolio' OR LastName = 'Fuller'
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 25;
- 为什么这应该有效?
- 什么时候应该使用这个?
【问题讨论】:
-
“当我使用
GROUP BY而不是WHERE子句时,我学会了使用HAVING” 你学错了。WHERE始终是允许的。HAVING用于根据聚合函数过滤结果,例如查询中的COUNT,它不会替换WHERE。WHERE是迄今为止不使用聚合函数的子句更合适的位置(再次,如上所示)。 -
我不能写 HAVING COUNT(Orders.OrderID) > 25 和 (LastName = 'Davolio' OR LastName = 'Fuller') 给我同样的结果。在这种情况下哪里是多余的
-
您可以,但不建议这样做。我怀疑这样的查询也会降低性能,因为 RDBMS 会聚合
LastName的 all 值然后过滤,而不是过滤然后聚合。这意味着需要进行表扫描(我没有对此进行测试,但HAVINGis processed after theGROUP BY所以这似乎是合乎逻辑的)。 -
可能优化器正在重写您的查询以隐式使用离散值谓词作为实际的
WHERE并帮助您摆脱困境。正如@Larnu(正确)指出的那样,您可以做很多您可能不应该做的事情。知道如何区分差异,而不是仅仅“因为它有效”而继续前进,这对你很有帮助。 -
看看一个 very 简单的查询,是的,优化器似乎是(正如@paneerakbari 所说)“拯救你”,它有效地传播了该子句
LastName IN ('Davolio','Fuller')到WHERE而不是HAVING,因为它执行查找并期望 18 行,但我怀疑在更复杂的查询中,您可能不会那么幸运。 db<>fiddle
标签: sql sql-server tsql