聚合函数
GROUP BY分组
按照department_id分组,查询department_id和该分组中员工的平均工资
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
按照相同的department_id和job_id分组,查询分组中员工的平均工资和其他信息
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;
GROUP BY中使用WITH ROLLUP
使用 WITH ROLLUP
关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量。
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
WITH ROLLUP;
注意:当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
WHERE department_id > 80
WITH ROLLUP;# 报错
HAVING
当使用聚合函数时(如MAX,AVG),不能使用WHERE来设置条件。
非法使用聚合函数 :
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
WHERE department_id > 80;# 报错
我们应该使用HAVING来设置条件
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
HAVING department_id > 80;
并且,HAVING应该只在有GROUP BY的语句中使用(尽管不会报错)
查询部门为10,20,30,40中最高工资比1w高的部门信息:
SELECT d.department_id, department_name, d.location_id, MAX(salary)
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IN (10,20,30,40)
GROUP BY department_id
HAVING MAX(salary) > 10000;
WHERE与HAVING对比:
优点 | 缺点 | |
---|---|---|
WHERE | 先筛选数据再关联,执行效率高 | 不能使用分组中的计算函数进行筛选 |
HAVING | 可以使用分组中的计算函数 | 在最后的结果集中进行筛选,执行效率较低 |
开发中的选择:
WHERE 和 HAVING 也不是互相排斥的,我们可以在一个查询里面同时使用 WHERE 和 HAVING。包含分组统计函数的条件用 HAVING,普通条件用 WHERE。这样,我们就既利用了 WHERE 条件的高效快速,又发挥了 HAVING 可以使用包含分组统计函数的查询条件的优点。当数据量特别大的时候,运行效率会有很大的差别。
SELECT底层逻辑
查询的结构
#方式1:
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
#方式2:
SELECT ...,....,...
FROM ... JOIN ...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
#其中:
#(1)from:从哪些表中筛选
#(2)on:关联多表查询时,去除笛卡尔积
#(3)where:从表中筛选的条件
#(4)group by:分组依据
#(5)having:在统计结果中再次筛选
#(6)order by:排序
#(7)limit:分页