GROUP BY
子句在 SQL 中的用途是将查询结果集中的数据分为若干组,并对每一组数据执行聚合操作,如 SUM
、AVG
、MAX
、MIN
、COUNT
等。每个组通常是根据一个或多个列的值来定义的。
基本语法
SELECT column1, AGGREGATE_FUNCTION(column2)
FROM table
GROUP BY column1;
这里,column1
是分组依据的列,而 AGGREGATE_FUNCTION(column2)
是对每组应用的聚合函数。where是在group by前筛选,having是在group by之后也就是聚合之后筛选。
注意事项:
- 非聚合列:在
SELECT
语句中,除了聚合函数计算的列外,其他所有列都应该出现在GROUP BY
子句中。否则,查询可能会返回错误,因为非聚合列的值在组内不是唯一的。 - 聚合函数:
GROUP BY
常与聚合函数结合使用。聚合函数会对每个组中的行进行计算,返回单个值。 - 唯一性:如果
GROUP BY
子句中的列是表的主键或具有唯一约束,则可以安全地选择该表中的其他列,因为主键或唯一列值能唯一确定其他列的值。 - 排序:
GROUP BY
也会影响结果的排序。默认情况下,MySQL 和 PostgreSQL 会根据GROUP BY
子句中的列对结果进行排序。如果需要不同的排序,可以使用ORDER BY
子句。
对group by的深入理解
使用 GROUP BY
子句时,查询的结果集中的每行都代表了一个分组。
用一道题来举例子:
看一下正确的代码
select info.dept_no,d.dept_name,title,count(info.emp_no)
from(
select de.emp_no emp_no,de.dept_no dept_no,t.title title
from dept_emp de
join titles t
on de.emp_no=t.emp_no
) info
left join departments d
on d.dept_no=info.dept_no
group by info.dept_no,d.dept_name,info.title
order by d.dept_no asc,title asc
这里重点理解一下group by的三个为什么这么写
——GROUP BY
子句告诉数据库:对于每一个独特的 dept_no
、dept_name
和 title
组合,给我一个行,并且用 COUNT()
函数计算出每个组合中 emp_no
的数量;如果只按 `info.title` 分组,那么数据库只会按 `title` 列的不同值分组,忽略 `dept_no` 和 `dept_name`,导致同一个 `title` 在不同的部门中被合并到一起,而不是按部门和职位独立计数。
也就是说,GROUP BY
的定义就是将那些有相同值的行聚合到一起。这就意味着,即便是在分组的列中有重复的值,结果集中也只会显示每个唯一值的单个实例。
知识点补充:在where子句中不能使用聚合函数进行比较,where子句是用来筛选行的,它在每一行上独立进行条件判断。此时,表中的每一行还没有被聚合,因此在where子句中使用聚合函数没有明确的定义在这里没有定义明确的含义:
select *
from employees
where hire_date=max(hire_date)
正确的写法:
SELECT *
FROM employees
WHERE hire_date = (
SELECT MAX(hire_date)
FROM employees
)