MySQL分组查询

Posted 风萧萧路漫漫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL分组查询相关的知识,希望对你有一定的参考价值。

语法:
⑥SELECT 分组函数,列(此列要出现在 GROUP BY的后面)
①FROM 表
②【WHERE 筛选条件】
③GROUP BY 分组的列
④【having 分组后的筛选】
⑦【ORDER BY 按什么排序】
注意:查询列表是特殊的,必须是分组函数后和GROUP BY后出现的字段

特点:
1.分组查询中的筛选条件分为两类

筛选的数据源不一样 位置  关键字
分组前筛选:原始表,库里真实存在的表 GROUP BY 前 WHERE  WHERE
分组后筛选:分组后的结果集  GROUP BY 后 HAVING  HAVING
  • 分组函数做条件肯定放在having子句中:原因筛选条件原始表中没有
  • 分组后的字段做筛选条件,放在where和having都行。
  • 出于性能的考虑:能用分组前筛选的就优先使用分组前筛选

2.都可以按什么分组

  • GROUP BY 子句支持单个字段分组,多个字段分组(字段之间用逗号隔开)没有顺序要求,也可以用表达式或函数

3.也可以添加排序,放在整个分组查询最后

GROUP BY、HAVING 都支持别名,where不支持别名

GROUP BY、HAVING后加别名。Oracle中不支持,mysql支持

#查询每个部门的平均工资

SELECT AVG(salary) FROM employees;

 


#简单的分组查询
案例1:查询每个工种的最高工资

SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id;

案例2:查询每个位置上的部门个数

SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;

 


#添加筛选条件
案例1:查询邮箱中包含字母a字符的,每个部门的平均工资

SELECT AVG(salary),department_id
FROM employees
WHERE email LIKE %a%
GROUP BY department_id;

案例2:查询有奖金的每个领导手下员工的最高工资

SELECT MAX(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL#有奖金
GROUP BY manager_id;

 


#添加复杂的筛选条件
案例1:查询那个部门的员工个数大于2
#1.查询每个部门的员工个数

SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;

#2.根据1.的结果进行筛选,查询哪个部门的员工个数大于2

SELECT COUNT(*),department_id
FROM employees
WHERE COUNT(*)>2
GROUP BY department_id;

报错无效的使用Invalid use of group function

WHERE是根据原始数据进行筛选,它要紧更着表后面,因为是:找表、筛选、显示、排序。

WHERE是分组前的筛选

这时候就需要新的关键字 HAVING,实现分组后的筛选

SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;

 

#案例2:查询每个工种有奖金的员工的最高工资大于12000的工种编号和最高工资

思路
先分组再筛选
#1.查询每个工种有奖金的最高工资

SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id;

 

#2.根据1的结果继续筛选,最高工资>12000

SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;

 

#案例3:查询领导编号大于102的每个领导手下的最低工资大于5000的领导编号是哪个,以及其最低工资
#1查询领导每个领导手下的最低工资

SELECT MIN(salary),manager_id
FROM employees
GROUP BY manager_id

查询出最低工资按照领导编号分组
#2.添加筛选条件

SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;

如果筛选的条件原始表就有就使用where

如果结果需要在筛选的结果上筛选那么就用 HAVING

 

#按函数表达或函数分组
#案例1:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的有哪些
#1.查询每个员工的姓名长度

SELECT COUNT(*),LENGTH(last_name) AS len_name #查询员工的个数,姓名的长度
FROM employees#在employee表中
GROUP BY LENGTH(last_name)#按姓名的长度分组
HAVING COUNT(*)>5;

 

SELECT COUNT(*) AS C,LENGTH(last_name) AS len_name #查询员工的个数,姓名的长度
FROM employees#在employee表中
GROUP BY len_name#按姓名的长度分组
HAVING C>5;

GROUP BY、HAVING 都支持别名,where不支持别名

GROUP BY、HAVING后加别名。Oracle中不支持,MySQL支持

#按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资

SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id;

 

#添加排序
#案例:查询每个部门每个工种的员工的平均工资,并按平均工资的高低显示

SELECT AVG(salary),department_id,job_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id,job_id
HAVING AVG(salary)>10000
ORDER BY AVG(salary) DESC;

 

以上是关于MySQL分组查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 怎样分组查询

mysql查询分组中最大的值

mysql 查询排序分组问题

MySQL笔记--MySQL分组函数和分组查询

分组查询操作(MySQL)

分组查询操作(MySQL)