如何在 SQL 中使用 GROUP BY 和 HAVING?

Buy owner data from various industry. Like home owner, car owner, business owner etc type owner contact details
Post Reply
suhashini25
Posts: 76
Joined: Tue Dec 03, 2024 5:03 am

如何在 SQL 中使用 GROUP BY 和 HAVING?

Post by suhashini25 »

如何在 SQL 中使用 GROUP BY 和 HAVING?700字文章


如何在 SQL 中使用 GROUP BY 和 HAVING?
在 SQL 中,GROUP BY 和 HAVING 子句是紧密相关的,它们通常一起使用,用于对数据进行聚合和过滤。理解它们的用途和工作方式对于编写复杂的分析查询至关重要。

1. GROUP BY 子句
GROUP BY 子句用于将查询结果中的行分组。分组是基于一个或多个列的值进行的,所有在这些指定列上具有相同值的行将被归入同一个组。一旦数据被分组,你就可以对每个组应用聚合函数(Aggregate Functions),例如 COUNT()、SUM()、AVG()、MIN()、MAX() 等,来计算每个组的汇总值。

数据收集: 从 FROM 子句指定的表中收集数据。
WHERE 过滤(如果存在): 如果有 WHERE 子句,它会在分组之前对原始行进行过滤。只有满足 WHERE 条件的行才会进入分组阶段。
分组: 数据库根据 GROUP BY 子句中指定的列的值,将过滤后的行划分成多个逻辑组。
聚合: 对每个组应用 SELECT 列表中指定的聚合函数,为每个组计算一个汇总值。
示例:计算每个部门的员工数量


查询根据 Department 列进行分组。
对于每个 Department 组,COUNT(*) 计算组内的行数(员工数量),AVG(Salary) 计算组内员工的平均工资。
2. HAVING 子句
HAVING 子句用于过滤 GROUP BY 子句创建的组。它 日本赌博数据 是在数据被分组和聚合之后应用的过滤条件。你不能在 WHERE 子句中使用聚合函数,因为 WHERE 是在分组之前对行进行过滤的。而 HAVING 就是为了解决在分组后对聚合结果进行过滤的需求。

基本语法:

SQL

SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition -- (可选) 行过滤器
GROUP BY column1, column3, ...
HAVING aggregate_condition -- 组过滤器,可以使用聚合函数
ORDER BY some_column; -- (可选) 最终结果排序
工作原理:

所有 GROUP BY 之前的步骤: 与上述 GROUP BY 的工作原理相同,包括 FROM、WHERE(如果存在)和 GROUP BY。
HAVING 过滤: 在分组和聚合完成之后,HAVING 子句会检查每个组,并根据 HAVING 条件筛选出满足条件的组。不满足条件的组将被从结果集中排除。
示例:查找员工数量超过 1 的部门

继续使用上面的 Employees 表和之前的分组查询:

首先,GROUP BY Department 和 COUNT(*)、AVG(Salary) 产生了与第一个示例相同的所有部门的聚合结果。
接着,HAVING COUNT(*) > 1 过滤掉了 Sales 部门(因为它的 NumberOfEmployees 是 1,不满足 > 1 的条件)。
WHERE 与 HAVING 的区别
这是初学者常遇到的混淆点:

WHERE 子句:

在分组之前对单个行进行过滤。
不能使用聚合函数。
优化器通常能更好地利用索引来加速 WHERE 过滤。
HAVING 子句:

在分组之后对**组(Group)**进行过滤。
可以(并且通常需要)使用聚合函数。
因为它在聚合后执行,所以无法利用行级索引来加速自身的过滤。
示例:查找工资高于 5000 的员工所在的部门,且该部门员工总数超过 1

FROM Employees: 选取所有员工。
WHERE Salary > 5000: 过滤出王五 (IT, 6000) 和 赵六 (Sales, 5500)。
GROUP BY Department:
IT 部门组:王五
Sales 部门组:赵六
SELECT 和聚合函数:
IT 组:NumberOfEmployees = 1, AverageSalary = 6000
Sales 组:NumberOfEmployees = 1, AverageSalary = 5500
HAVING COUNT(*) > 1: 过滤掉 IT 组 (Count=1) 和 Sales 组 (Count=1)。
查询结果:

-- (空结果集,因为没有部门的员工数量超过1)
这个例子清晰地展示了 WHERE 和 HAVING 在查询处理阶段和过滤对象上的差异。正确地使用它们是编写高效和准确 SQL 查询的关键。
Post Reply