Group By、Having用法总结
目录
- Group By、Having用法总结
- 一、 GROUP BY 用法
- 二、 HAVING 用法
- 三、 `GROUP BY` 和 `HAVING` 的常见踩雷点
- 3.1 `GROUP BY` 选择的列必须出现在 `SELECT` 中(🤣最重要的一点)
- 3.2 `HAVING` 与 `WHERE` 的区别
- 3.3 `GROUP BY` 可以有多个列
- 3.4 `GROUP BY` 和 `ORDER BY` 的关系
- 3.5 聚合函数的计算顺序
- 3.6 `HAVING` 中的聚合函数和常量比较
- 3.7 避免在 `HAVING` 中做不必要的计算
- 各位看客老爷 万福金安🤣一键三连呀🤣🤣🤣
一、 GROUP BY 用法
GROUP BY
子句用来根据一个或多个列将结果集进行分组,常与聚合函数(如 COUNT()
, SUM()
, AVG()
, MAX()
, MIN()
)一起使用。
SELECT column1, column2, aggregate_function(column3)
FROM table
GROUP BY column1, column2;
SELECT department, AVG(salary)
FROM employees
GROUP BY department;
-- 根据 `department` 列对 `employees` 表进行分组,然后计算每个部门的平均工资。
二、 HAVING 用法
HAVING
子句用于过滤GROUP BY
生成的分组数据。- 它与
WHERE
子句的不同之处在于,WHERE
在分组前过滤行,而HAVING
是在分组后对结果进行过滤。
SELECT column1, aggregate_function(column2)
FROM table
GROUP BY column1
HAVING aggregate_function(column2) condition;
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
-- 返回平均工资大于 50000 的部门。
三、 GROUP BY
和 HAVING
的常见踩雷点
3.1 GROUP BY
选择的列必须出现在 SELECT
中(🤣最重要的一点)
-
使用
GROUP BY
时,SELECT
中的非聚合列必须出现在GROUP BY
子句中,或者是聚合函数的一部分。 -
不能在 GROUP BY 后直接选择没有参与分组或没有应用聚合函数的字段,否则 SQL 会报错。
-
错误示例:
SELECT department, name, AVG(salary) FROM employees GROUP BY department;
name
列没有出现在GROUP BY
中,也没有被聚合,会引发错误。 -
SQL 不知道如何处理 name,因为它没有被分组(GROUP BY 只会根据 department 分组),也没有被聚合(没有 MAX(name) 或 MIN(name))。
-
可以去掉 name 字段,或者使用聚合函数对它进行处理。
SELECT department, MIN(name), AVG(salary) FROM employees GROUP BY department;
Tips:
-
在分组后,SQL 已经将多个行数据合并为一个分组(代表一组相关的记录)。
-
在这个合并的过程中,SQL 无法直接决定非分组字段应该取什么值,因为每个字段的值在一个分组中可能是不同的。Eg.如果一个部门有多个员工,你无法直接从中选择一个特定的员工姓名,因为在一个分组中,有多个员工姓名。
-
That’s why,SQL 只允许你选择分组字段或通过聚合函数“汇总”一个分组中的多个行。
来两个正确用法巩固一下脑子哈哈:
(不能在 GROUP BY 后的 SELECT 中选择没有聚合的字段,或者没有在 GROUP BY 中出现的字段!!!)
SELECT department, job_title, AVG(salary)
FROM employees
GROUP BY department, job_title;
SELECT department, job_title, MAX(employee_name), AVG(salary)
FROM employees
GROUP BY department, job_title;
3.2 HAVING
与 WHERE
的区别
WHERE
用于过滤行数据,而HAVING
用于过滤分组数据。- 不能在
HAVING
中使用列名,而必须使用聚合函数或已经被分组的列。 - 错误示例:
SELECT department, COUNT(*) FROM employees GROUP BY department HAVING department = 'HR'; -- 错误,因为 department 在 HAVING 中不应该用
3.3 GROUP BY
可以有多个列
- 可以在
GROUP BY
中使用多个列,创建更细致的分组。
按照 department
和 job_title
进行多列分组:
SELECT department, job_title, COUNT(*)
FROM employees
GROUP BY department, job_title;
3.4 GROUP BY
和 ORDER BY
的关系
GROUP BY
用于分组数据,而ORDER BY
用于排序数据。它们的顺序不一样。- 可以在
GROUP BY
后面使用ORDER BY
来对结果进行排序。
按平均工资降序排序。:
SELECT department, AVG(salary)
FROM employees
GROUP BY department
ORDER BY AVG(salary) DESC;
-- 按平均工资降序排序。
3.5 聚合函数的计算顺序
-
GROUP BY
会先分组,然后应用聚合函数。如果需要在聚合函数的结果上进一步过滤数据,应该使用HAVING
而不是WHERE
。SELECT department, SUM(salary) FROM employees WHERE hire_date > '2020-01-01' -- WHERE 在聚合之前 GROUP BY department;
3.6 HAVING
中的聚合函数和常量比较
-
在
HAVING
子句中,通常会看到聚合函数与某个常量进行比较。这样做没有问题,但必须要确保聚合函数的语法正确。SELECT department, COUNT(*) FROM employees GROUP BY department HAVING COUNT(*) > 10; -- 这个是正确的
3.7 避免在 HAVING
中做不必要的计算
-
不要在
HAVING
中做不必要的计算,可能会导致性能下降。如果能在WHERE
中提前过滤,就避免使用HAVING
。SELECT department, SUM(salary) FROM employees WHERE salary > 50000 -- 提前过滤 GROUP BY department;