目录
一、聚合函数
1、常见的几个聚合函数
1.1 AVG/SUM
只适用于数值类型的字段
SELECT AVG(salary),SUM(salary),AVG(salary)*107 FROM employees;
mysql> SELECT AVG(salary),SUM(salary),AVG(salary)*107 FROM employees;
+-------------+-------------+-----------------+
| AVG(salary) | SUM(salary) | AVG(salary)*107 |
+-------------+-------------+-----------------+
| 6461.682243 | 691400.00 | 691400.000000 |
+-------------+-------------+-----------------+
1.2 MAX/MIN
适用于数值类型的字段、字符串类型、日期时间类型
SELECT MAX(salary),MIN(salary) FROM employees;
mysql> SELECT MAX(salary),MIN(salary) FROM employees;
+-------------+-------------+
| MAX(salary) | MIN(salary) |
+-------------+-------------+
| 24000.00 | 2100.00 |
+-------------+-------------+
1 row in set (0.00 sec)
SELECT MAX(last_name),MIN(last_name),MAX(hiredate),MIN(hiredate) FROM employees;
mysql> SELECT MAX(last_name),MIN(last_name),MAX(hiredate),MIN(hiredate) FROM employees;
+----------------+----------------+---------------------+---------------------+
| MAX(last_name) | MIN(last_name) | MAX(hiredate) | MIN(hiredate) |
+----------------+----------------+---------------------+---------------------+
| Zlotkey | Abel | 2016-03-03 00:00:00 | 1992-04-03 00:00:00 |
+----------------+----------------+---------------------+---------------------+
1 row in set (0.00 sec)
1.3 COUNT
作用:计算指定字段在查询结果中出现的个数(不包含null值)
SELECT COUNT(employee_id),COUNT(salary) FROM employees;
mysql> SELECT COUNT(employee_id),COUNT(salary) FROM employees;
+--------------------+---------------+
| COUNT(employee_id) | COUNT(salary) |
+--------------------+---------------+
| 107 | 107 |
+--------------------+---------------+
1 row in set (0.00 sec
SELECT COUNT(1),COUNT(2),COUNT(*) FROM employees; //把每条数据拿数字或符号来充当,那么一共有几条记录,结果就是几。
SELECT COUNT(commission_pct) FROM employees; //结果为35条不为NULL的值
注:以上聚合函数都会自动过滤NULL值
2、GROUP BY
需求:查询各个部门的平均工资,最高工资
SELECT department_id,AVG(salary),SUm(salary) FROM employees GROUP BY department_id;
mysql> SELECT department_id,AVG(salary),SUm(salary) FROM employees GROUP BY department_id;
+---------------+--------------+-------------+
| department_id | AVG(salary) | SUm(salary) |
+---------------+--------------+-------------+
| NULL | 7000.000000 | 7000.00 |
| 10 | 4400.000000 | 4400.00 |
| 20 | 9500.000000 | 19000.00 |
| 30 | 4150.000000 | 24900.00 |
| 40 | 6500.000000 | 6500.00 |
| 50 | 3475.555556 | 156400.00 |
| 60 | 5760.000000 | 28800.00 |
| 70 | 10000.000000 | 10000.00 |
| 80 | 8955.882353 | 304500.00 |
| 90 | 19333.333333 | 58000.00 |
| 100 | 8600.000000 | 51600.00 |
| 110 | 10150.000000 | 20300.00 |
+---------------+--------------+-------------+
需求:查询各个job_id的平均工资
SELECT job_id,AVG(salary) FROM employees GROUP BY job_id;
mysql> SELECT job_id,AVG(salary) FROM employees GROUP BY job_id;
+------------+--------------+
| job_id | AVG(salary) |
+------------+--------------+
| AC_ACCOUNT | 8300.000000 |
| AC_MGR | 12000.000000 |
| AD_ASST | 4400.000000 |
| AD_PRES | 24000.000000 |
| AD_VP | 17000.000000 |
| FI_ACCOUNT | 7920.000000 |
| FI_MGR | 12000.000000 |
| HR_REP | 6500.000000 |
| IT_PROG | 5760.000000 |
| MK_MAN | 13000.000000 |
| MK_REP | 6000.000000 |
| PR_REP | 10000.000000 |
| PU_CLERK | 2780.000000 |
| PU_MAN | 11000.000000 |
| SA_MAN | 12200.000000 |
| SA_REP | 8350.000000 |
| SH_CLERK | 3215.000000 |
| ST_CLERK | 2785.000000 |
| ST_MAN | 7280.000000 |
+------------+--------------+
19 rows in set (0.01 sec)
需求:查询各个department_id,job_id的平均工资
SELECT department_id,job_id,AVG(salary) FROM employees GROUP BY department_id,job_id;
mysql> SELECT department_id,job_id,AVG(salary) FROM employees GROUP BY department_id,job_id;
+---------------+------------+--------------+
| department_id | job_id | AVG(salary) |
+---------------+------------+--------------+
| NULL | SA_REP | 7000.000000 |
| 10 | AD_ASST | 4400.000000 |
| 20 | MK_MAN | 13000.000000 |
| 20 | MK_REP | 6000.000000 |
| 30 | PU_CLERK | 2780.000000 |
| 30 | PU_MAN | 11000.000000 |
| 40 | HR_REP | 6500.000000 |
| 50 | SH_CLERK | 3215.000000 |
| 50 | ST_CLERK | 2785.000000 |
| 50 | ST_MAN | 7280.000000 |
| 60 | IT_PROG | 5760.000000 |
| 70 | PR_REP | 10000.000000 |
| 80 | SA_MAN | 12200.000000 |
| 80 | SA_REP | 8396.551724 |
| 90 | AD_PRES | 24000.000000 |
| 90 | AD_VP | 17000.000000 |
| 100 | FI_ACCOUNT | 7920.000000 |
| 100 | FI_MGR | 12000.000000 |
| 110 | AC_ACCOUNT | 8300.000000 |
| 110 | AC_MGR | 12000.000000 |
+---------------+------------+--------------+
20 rows in set (0.00 sec
SELECT department_id,job_id,AVG(salary) FROM employees GROUP BY job_id,department_id;
//和上面结果出现的一样,只是分队的顺序不一样,先按前面的进行分组,再按后面的进行分组
mysql> SELECT department_id,job_id,AVG(salary) FROM employees GROUP BY job_id,department_id;
+---------------+------------+--------------+
| department_id | job_id | AVG(salary) |
+---------------+------------+--------------+
| 110 | AC_ACCOUNT | 8300.000000 |
| 110 | AC_MGR | 12000.000000 |
| 10 | AD_ASST | 4400.000000 |
| 90 | AD_PRES | 24000.000000 |
| 90 | AD_VP | 17000.000000 |
| 100 | FI_ACCOUNT | 7920.000000 |
| 100 | FI_MGR | 12000.000000 |
| 40 | HR_REP | 6500.000000 |
| 60 | IT_PROG | 5760.000000 |
| 20 | MK_MAN | 13000.000000 |
| 20 | MK_REP | 6000.000000 |
| 70 | PR_REP | 10000.000000 |
| 30 | PU_CLERK | 2780.000000 |
| 30 | PU_MAN | 11000.000000 |
| 80 | SA_MAN | 12200.000000 |
| NULL | SA_REP | 7000.000000 |
| 80 | SA_REP | 8396.551724 |
| 50 | SH_CLERK | 3215.000000 |
| 50 | ST_CLERK | 2785.000000 |
| 50 | ST_MAN | 7280.000000 |
+---------------+------------+--------------+
20 rows in set (0.00 sec)
注意点1:
注意点2:
WITH ROLLUP会把所有数据再进行一次统计总和
3、HAVING
HAVING的作用:用来过滤数据的
练习:查询各个部门中最高的工资比10000高的部门信息
注意点1: 如果过滤条件中使用了聚合函数,则必须使用HAVING来替换WHERE。否则会报错
注意点2:HAVING必须声明再GROUP BY的后面
开发中,我们使用HAVING的前提是SQL中使用了GROUP BY
练习:查询部门id为10,20,30,40这4个部门中最高工资比10000高的部门信息
方法一:SELECT department_id,MAX(salary) FROM employees WHERE department_id IN(10,20,30,40) GROUP BY department_id HAVING MAX(salary>10000);
mysql> SELECT department_id,MAX(salary) FROM employees WHERE department_id IN(10,20,30,40) GROUP BY department_id HAVING MAX(salary>10000);
+---------------+-------------+
| department_id | MAX(salary) |
+---------------+-------------+
| 20 | 13000.00 |
| 30 | 11000.00 |
+---------------+-------------+
2 rows in set (0.01 sec)
方法二:SELECT department_id,MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary>10000) AND department_id IN(10,20,30,40);
mysql> SELECT department_id,MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary>10000) AND department_id IN(10,20,30,40);
+---------------+-------------+
| department_id | MAX(salary) |
+---------------+-------------+
| 20 | 13000.00 |
| 30 | 11000.00 |
+---------------+-------------+
2 rows in set (0.01 sec)
4、SQL底层执行原理
4.1 SELECT 语句的完整结构
书写顺序:
4.2 SQL语句的执行过程
从顺序中也可以看出,起了别名不能在WHERE中使用