在 SQL 中,WHERE 子句和 HAVING 子句都用于过滤数据,但它们在 SQL 查询的执行顺序、过滤对象以及是否可以使用聚合函数方面存在本质区别。理解这两者的不同是编写高效和准确 SQL 查询的关键。
1. WHERE 子句
用途: WHERE 子句用于在数据被**分组(GROUP BY)之前,对单个行(individual rows)**进行过滤。它适用于原始数据表中的每一行,并根据指定的条件决定哪些行应该被包含在查询结果中(或进入后续的分组阶段)。
位置: 在 FROM 子句之后,GROUP BY 子句之前。
能否使用聚合函数: 不能直接在 WHERE 子句中使用聚合函数(如 COUNT(), SUM(), AVG(), MIN(), MAX()),因为 WHERE 是在聚合发生之前执行的。
适用语句: 可以用于 SELECT, UPDATE, DELETE 语句。
基本语法:
此查询会在 Employees 表中逐行检查 Salary 列,只返回那些 Salary 值大于 50000 的员工记录。这个过滤操作发生在任何聚合之前。
2. HAVING 子句
用途: HAVING 子句用于在数据被**分组(GROUP BY)和聚合(aggregated)之后,对组(groups)**进行过滤。它作用于聚合函数的结果。
位置: 在 GROUP BY 子句之后,ORDER BY 子句之前。如果查 俄罗斯赌博数据 询中没有 GROUP BY 子句,但使用了聚合函数,那么 HAVING 子句会作用于整个结果集作为一个单一的组。
能否使用聚合函数: 可以使用聚合函数。这是 HAVING 子句的主要特点和存在理由。
适用语句: 通常只能用于 SELECT 语句。
基本语法:
首先,GROUP BY Department 会将员工按部门分组。
然后,COUNT(EmployeeID) 会计算每个部门的员工数量。
最后,HAVING COUNT(EmployeeID) > 2 会过滤这些组,只保留员工数量大于 2 的部门。
3. WHERE 与 HAVING 的关键区别总结
特性 WHERE 子句 HAVING 子句
过滤对象 原始数据表的单个行。 GROUP BY 子句创建的组。
执行顺序 在 FROM 和 JOIN 之后,在 GROUP BY 之前执行。 在 GROUP BY 之后,在聚合函数计算之后执行。
聚合函数 不能直接使用聚合函数。 可以使用聚合函数。
性能 通常更高效,因为它在分组前减少了要处理的行数。 可能会慢一些,因为它在所有分组和聚合计算完成后才过滤。
适用语句 SELECT, UPDATE, DELETE。 主要用于 SELECT。
Export to Sheets
4. 同时使用 WHERE 和 HAVING
在复杂的查询中,WHERE 和 HAVING 可以同时使用。在这种情况下,它们的执行顺序非常重要:
FROM 和 JOIN:确定要查询的表和它们的连接方式。
WHERE:对原始数据进行行级别过滤。只有满足 WHERE 条件的行才会被传递到下一步。
GROUP BY:将经过 WHERE 过滤后的行进行分组。
HAVING:对分组后的结果进行组级别过滤,通常涉及聚合函数。
SELECT:选择最终的列,并应用别名、表达式等。
ORDER BY:对最终结果进行排序。
示例:查找平均工资高于 60000 且部门位于 'Sales' 或 'Marketing' 的部门
SELECT Department, AVG(Salary) AS AverageSalary, COUNT(EmployeeID) AS NumberOfEmployees
FROM Employees
WHERE Department IN ('Sales', 'Marketing') -- 首先过滤掉不是Sales或Marketing部门的员工
GROUP BY Department
HAVING AVG(Salary) > 60000; -- 然后对剩下的部门(Sales和Marketing)进行聚合后过滤
解释:
WHERE Department IN ('Sales', 'Marketing'):在分组之前,它会先排除所有不在 'Sales' 或 'Marketing' 部门的员工行。这减少了需要分组的数据量。
GROUP BY Department:然后,剩余的员工(只包含 Sales 和 Marketing 部门的)会按部门分组。
HAVING AVG(Salary) > 60000:最后,系统会计算每个组(即 Sales 部门和 Marketing 部门)的平均工资,并只返回那些平均工资大于 60000 的部门。
通过这种方式,WHERE 和 HAVING 各司其职,共同完成了复杂的过滤任务,并且通常能提高查询的效率,因为 WHERE 提前减少了数据量。
WHERE 和 HAVING 子句之间有什么区别?
-
- Posts: 76
- Joined: Tue Dec 03, 2024 5:03 am