模块课程(3/4)
使用 GROUP BY 进行分组
在模块 2 中,您了解到 COUNT(*)、AVG(...)、SUM(...) 减少了所有
行到单个结果行。但如果你想要平均工资怎么办?
针对每个部门,而不是针对整个公司?你想要一行per
组。这是 GROUP BY 的工作。
语法
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column;用英语阅读:“将行分成具有相同值的组
grouping_column,并为每个组计算聚合“。
-- Average salary per department:
SELECT department_id, AVG(salary) AS average
FROM employees
GROUP BY department_id;结果对于在中找到的每个不同的 department_id** 有一行
employees。您将获得 5 行:4 个部门各一行(1、2、
3、4) 加上一个 NULL (Andrea Costa)。
使用 JOIN 获得可读的名称
通常您希望按 department_id 进行分组,但显示该对象的名称
部门。您可以将 GROUP BY 与 JOIN 结合起来:
SELECT d.name AS department,
COUNT(*) AS count,
AVG(e.salary) AS average_salary
FROM employees AS e
JOIN departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;这是一个成熟的商业智能查询:三行 告诉您每个部门有多少员工以及他们的收入 平均值,从大到小排序。
黄金法则
当您使用 GROUP BY 时,SELECT 中的每一列都必须是:
- 分组列之一(例如
department_id、d.name),或 - 在聚合函数内部(例如
AVG(salary)、COUNT(*))。
-- ERROR: first_name is neither in GROUP BY nor inside an aggregate
SELECT department_id, first_name, AVG(salary)
FROM employees
GROUP BY department_id;PostgreSQL 返回显式错误(“列必须出现在 GROUP BY 中)
子句或在聚合函数中使用“)。这是常见的前几周
错误:如果你看到它,停下来问问自己*“它的价值是什么
first_name 对于 3 人一组?"* — 没有单一的答案,并且
这就是引擎拒绝的原因。
尝试一下
对于每个部门,计算其包含多少员工。返回两列:部门名称 (departments.name) 和员工人数。每个部门一行。
显示提示
使用 COUNT(*) 进行聚合并按 d.name 进行分组。 SELECT 必须仅包含分组列和聚合。
3 次尝试后可用的解决方案
复习练习
对于每个部门 (departments.name),计算其员工的平均工资 (AVG(salary)),从最高到最低排序。
显示提示
AVG(e.salary) 作为总计,GROUP BY d.name,ORDER BY 平均 DESC。
3 次尝试后可用的解决方案