MySQL 之分組查詢
阿新 • • 發佈:2018-12-22
分組查詢
語法:
select 查詢列表
from 表
【where 篩選條件】
group by 分組的欄位
【order by 排序的欄位】;特點:
- 1、和分組函式一同查詢的欄位必須是group by後出現的欄位
- 2、篩選分為兩類:分組前篩選和分組後篩選
針對的表 位置 連線的關鍵字 分組前篩選 原始表 group by前 where 分組後篩選 group by後的結果集 group by後 having 問題1:分組函式做篩選能不能放在where後面
答:不能問題2:where——group by——having
一般來講,能用分組前篩選的,儘量使用分組前篩選,提高效率
- 3、分組可以按單個欄位也可以按多個欄位
- 4、可以搭配著排序使用
引入:查詢每個部門的員工個數
mysql> SELECT COUNT(*), department_id -> FROM employees -> GROUP BY department_id; +----------+---------------+ | COUNT(*) | department_id | +----------+---------------+ | 1 | NULL | | 1 | 10 | | 2 | 20 | | 6 | 30 | | 1 | 40 | | 45 | 50 | | 5 | 60 | | 1 | 70 | | 34 | 80 | | 3 | 90 | | 6 | 100 | | 2 | 110 | +----------+---------------+ 12 rows in set (0.00 sec)
1.簡單的分組
案例1:查詢每個工種的員工平均工資
mysql> SELECT AVG(salary), job_id -> FROM employees -> GROUP BY job_id; +--------------+------------+ | AVG(salary) | job_id | +--------------+------------+ | 8300.000000 | AC_ACCOUNT | | 12000.000000 | AC_MGR | | 4400.000000 | AD_ASST | | 24000.000000 | AD_PRES | | 17000.000000 | AD_VP | | 7920.000000 | FI_ACCOUNT | | 12000.000000 | FI_MGR | | 6500.000000 | HR_REP | | 5760.000000 | IT_PROG | | 13000.000000 | MK_MAN | | 6000.000000 | MK_REP | | 10000.000000 | PR_REP | | 2780.000000 | PU_CLERK | | 11000.000000 | PU_MAN | | 12200.000000 | SA_MAN | | 8350.000000 | SA_REP | | 3215.000000 | SH_CLERK | | 2785.000000 | ST_CLERK | | 7280.000000 | ST_MAN | +--------------+------------+ 19 rows in set (0.00 sec)
2、可以實現分組前的篩選
案例1:查詢郵箱中包含a字元的 每個部門的最高工資
mysql> SELECT MAX(salary), department_id, email
-> FROM employees
-> WHERE email LIKE '%a%'
-> GROUP BY department_id;
+-------------+---------------+----------+
| MAX(salary) | department_id | email |
+-------------+---------------+----------+
| 7000.00 | NULL | KGRANT |
| 4400.00 | 10 | JWHALEN |
| 13000.00 | 20 | MHARTSTE |
| 11000.00 | 30 | DRAPHEAL |
| 6500.00 | 40 | SMAVRIS |
| 8200.00 | 50 | AFRIPP |
| 9000.00 | 60 | AHUNOLD |
| 10000.00 | 70 | HBAER |
| 13500.00 | 80 | KPARTNER |
| 17000.00 | 90 | NKOCHHAR |
| 9000.00 | 100 | DFAVIET |
+-------------+---------------+----------+
11 rows in set (0.00 sec)
案例2:查詢有獎金的每個領導手下員工的平均工資
mysql> SELECT AVG(salary), manager_id
-> FROM employees
-> WHERE commission_pct IS NOT NULL
-> GROUP BY manager_id;
+--------------+------------+
| AVG(salary) | manager_id |
+--------------+------------+
| 12200.000000 | 100 |
| 8500.000000 | 145 |
| 8500.000000 | 146 |
| 7766.666667 | 147 |
| 8650.000000 | 148 |
| 8333.333333 | 149 |
+--------------+------------+
6 rows in set (0.00 sec)
3、分組後篩選
案例:查詢哪個部門的員工個數>5,步驟如下所示:
- ①查詢每個部門的員工個數
mysql> SELECT COUNT(*),department_id
-> FROM employees
-> GROUP BY department_id;
+----------+---------------+
| COUNT(*) | department_id |
+----------+---------------+
| 1 | NULL |
| 1 | 10 |
| 2 | 20 |
| 6 | 30 |
| 1 | 40 |
| 45 | 50 |
| 5 | 60 |
| 1 | 70 |
| 34 | 80 |
| 3 | 90 |
| 6 | 100 |
| 2 | 110 |
+----------+---------------+
12 rows in set (0.00 sec)
- ② 篩選剛才①結果
mysql> SELECT COUNT(*),department_id
-> FROM employees
-> GROUP BY department_id
-> HAVING COUNT(*)>5;
+----------+---------------+
| COUNT(*) | department_id |
+----------+---------------+
| 6 | 30 |
| 45 | 50 |
| 34 | 80 |
| 6 | 100 |
+----------+---------------+
4 rows in set (0.00 sec)
案例2:每個工種有獎金的員工的最高工資>10000的工種編號和最高工資
mysql> SELECT MAX(salary) AS max_salary, job_id
-> FROM employees
-> WHERE commission_pct IS NOT NULL
-> GROUP BY job_id
-> HAVING max_salary > 10000;
+------------+--------+
| max_salary | job_id |
+------------+--------+
| 14000.00 | SA_MAN |
| 11500.00 | SA_REP |
+------------+--------+
2 rows in set (0.00 sec)
案例3:領導編號>102的每個領導手下的最低工資大於5000的領導編號和最低工資
mysql> SELECT MIN(salary) min_salary, manager_id
-> FROM employees
-> WHERE manager_id > 102
-> GROUP BY manager_id
-> HAVING min_salary > 5000;
+------------+------------+
| min_salary | manager_id |
+------------+------------+
| 6900.00 | 108 |
| 7000.00 | 145 |
| 7000.00 | 146 |
| 6200.00 | 147 |
| 6100.00 | 148 |
| 6200.00 | 149 |
| 6000.00 | 201 |
| 8300.00 | 205 |
+------------+------------+
8 rows in set (0.00 sec)
4.新增排序
案例:每個工種有獎金的員工的最高工資>6000的工種編號和最高工資,按最高工資升序;
mysql> SELECT job_id, MAX(salary) max_salary
-> FROM employees
-> WHERE commission_pct IS NOT NULL
-> GROUP BY job_id
-> HAVING max_salary > 6000
-> ORDER BY max_salary DESC;
+--------+------------+
| job_id | max_salary |
+--------+------------+
| SA_MAN | 14000.00 |
| SA_REP | 11500.00 |
+--------+------------+
2 rows in set (0.00 sec)
5.按多個欄位分組
案例:查詢每個工種每個部門的最低工資,並按最低工資降序
mysql> SELECT MIN(salary) min_salary, job_id, department_id
-> FROM employees
-> GROUP BY job_id, department_id
-> ORDER BY min_salary DESC;
+------------+------------+---------------+
| min_salary | job_id | department_id |
+------------+------------+---------------+
| 24000.00 | AD_PRES | 90 |
| 17000.00 | AD_VP | 90 |
| 13000.00 | MK_MAN | 20 |
| 12000.00 | AC_MGR | 110 |
| 12000.00 | FI_MGR | 100 |
| 11000.00 | PU_MAN | 30 |
| 10500.00 | SA_MAN | 80 |
| 10000.00 | PR_REP | 70 |
| 8300.00 | AC_ACCOUNT | 110 |
| 7000.00 | SA_REP | NULL |
| 6900.00 | FI_ACCOUNT | 100 |
| 6500.00 | HR_REP | 40 |
| 6100.00 | SA_REP | 80 |
| 6000.00 | MK_REP | 20 |
| 5800.00 | ST_MAN | 50 |
| 4400.00 | AD_ASST | 10 |
| 4200.00 | IT_PROG | 60 |
| 2500.00 | SH_CLERK | 50 |
| 2500.00 | PU_CLERK | 30 |
| 2100.00 | ST_CLERK | 50 |
+------------+------------+---------------+
20 rows in set (0.00 sec)