【MYSQL】聚合函数介绍

 聚合函数介绍

1.1 AVG和SUM函数

1.2 MIN和MAX函数

1.3 COUNT函数

1.4 GROUP BY

1.5 Having

 

1.1 AVG和SUM函数

可以对数值型数据使用AVG 和 SUM 函数。

 SELECT AVG(salary), MAX(salary),MIN(salary), SUM(salary) FROM employees WHERE job_id LIKE '%REP%';
/*
+-------------+-------------+-------------+-------------+
| AVG(salary) | MAX(salary) | MIN(salary) | SUM(salary) |
+-------------+-------------+-------------+-------------+
| 8272.727273 |    11500.00 |     6000.00 |   273000.00 |
+-------------+-------------+-------------+-------------+
*/

1.2 MIN和MAX函数

可以对任意数据类型的数据使用 MIN 和 MAX 函数。

SELECT MIN(hire_date), MAX(hire_date)
FROM employees;
/*
+----------------+----------------+
| MIN(hire_date) | MAX(hire_date) |
+----------------+----------------+
| 1987-06-17     | 2000-04-21     |
+----------------+----------------+
*/

1.3 COUNT函数

  • COUNT(*)或COUNT(任意数字)返回表中记录总数,适用于任意数据类型。COUNT(任意数字),相当与用数字填充表的第一例。
SELECT COUNT(*)
FROM employees
WHERE department_id = 50;
/*
+----------+
| COUNT(*) |
+----------+
|       45 |
+----------+
*/

COUNT(字段) 计算指定字段出现的个数时,是不计算NULL值的,相当于以下sql代码:

SELECT commission_pct  FROM employees
WHERE commission_pct IS NOT NULL;

例子

SELECT COUNT(commission_pct)
FROM employees
WHERE department_id = 50;
/*
+-----------------------+
| COUNT(commission_pct) |
+-----------------------+
|                     0 |
+-----------------------+
*/

需求:查询公司中平均奖金率

SELECT SUM (commission_pct) / COUNT(IFNULL (commission_pct,0)),AVG(IFNULL(comnission_pct,0))
FROM employees;

问题:用count(*), count(1),count(列名)谁好呢?
如何需要统计表中的记录数,使用count(*)、count(1)、count(具体字段)

哪个效率更高呢?

如果使用的是MyISAM存储引擎,则三者效率相同,都是o(1),有mate
如果使用的是InnoDB存储引擎,则三者效率:count(*) '= ‘count(1) '> count(字段),强两者会找优化的方式,后者只能执行没有优化的方式。



 1.4 GROUP BY

特性:

1、SELECT中出现的非聚合函数的字段必须声明在GROUP BY中。GROUP BY中声明的字段可以不出现在SELECT中。

2、 GROUP BY声明在FROM后面、WHERE后面,ORDER BY前面、LIMIT前面

3、MysQL中GROUP BY中使用wiht ROLLUP 不要合order by 一起使用。

格式

SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];

在SELECT列表中所有未包含在组函数中的列都应该包含在 GROUP BY子句中

SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id ;
/*
+---------------+--------------+
| department_id | AVG(salary)  |
+---------------+--------------+
|          NULL |  7000.000000 |
|            10 |  4400.000000 |
|            20 |  9500.000000 |
|            30 |  4150.000000 |
|            40 |  6500.000000 |
|            50 |  3475.555556 |
|            60 |  5760.000000 |
|            70 | 10000.000000 |
|            80 |  8955.882353 |
|            90 | 19333.333333 |
|           100 |  8600.000000 |
|           110 | 10150.000000 |
+---------------+--------------+
*/

包含在 GROUP BY 子句中的列不必包含在SELECT 列表中

SELECT AVG(salary) FROM employees 
GROUP BY department_id ;
/*
+--------------+
| AVG(salary)  |
+--------------+
|  7000.000000 |
|  4400.000000 |
|  9500.000000 |
|  4150.000000 |
|  6500.000000 |
|  3475.555556 |
|  5760.000000 |
| 10000.000000 |
|  8955.882353 |
| 19333.333333 |
|  8600.000000 |
| 10150.000000 |
+--------------+
*/

使用多个列分组

SELECT department_id dept_id, job_id, SUM(salary)
FROM employees
GROUP BY department_id, job_id ;
/*
+---------+------------+-------------+
| dept_id | job_id     | SUM(salary) |
+---------+------------+-------------+
|    NULL | SA_REP     |     7000.00 |
|      10 | AD_ASST    |     4400.00 |
|      20 | MK_MAN     |    13000.00 |
|      20 | MK_REP     |     6000.00 |
|      30 | PU_CLERK   |    13900.00 |
|      30 | PU_MAN     |    11000.00 |
|      40 | HR_REP     |     6500.00 |
|      50 | SH_CLERK   |    64300.00 |
|      50 | ST_CLERK   |    55700.00 |
|      50 | ST_MAN     |    36400.00 |
|      60 | IT_PROG    |    28800.00 |
|      70 | PR_REP     |    10000.00 |
|      80 | SA_MAN     |    61000.00 |
|      80 | SA_REP     |   243500.00 |
|      90 | AD_PRES    |    24000.00 |
|      90 | AD_VP      |    34000.00 |
|     100 | FI_ACCOUNT |    39600.00 |
|     100 | FI_MGR     |    12000.00 |
|     110 | AC_ACCOUNT |     8300.00 |
|     110 | AC_MGR     |    12000.00 |
+---------+------------+-------------+
*/

在Mysql中 SELECT中出现的非聚合函数的字段必须声明在GROUP BY中。GROUP BY中声明的字段可以不出现在SELECT中。

错误写法

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

正确

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

使用 WITH ROLLUP 关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量。

SELECT department_id,AVG(salary)
FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;
/*
+---------------+--------------+
| department_id | AVG(salary)  |
+---------------+--------------+
|            90 | 19333.333333 |
|           100 |  8600.000000 |
|           110 | 10150.000000 |
|          NULL | 11809.090909 |
+---------------+--------------+
*/

注意:
当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的。

 1.5 Having 聚合函数

(1) 则必须在HAVING中聚合函数过滤条件 ,不能在where中使用聚合函数过滤条件。否则,报错。

(2)HAVING必须声明在GROUP BY的后面,HAVING 通常跟 GROUP BY 一起使用。
(3)当过滤条件中聚合函数时,则此过滤条件必须声明在HAVING中。
当过滤条件中设有聚合函数时,则此过滤条件声明在WHERE中或HAVING中都可以。但是,建议大家声明在WHere

SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000 ;
/*
+---------------+-------------+
| department_id | MAX(salary) |
+---------------+-------------+
|            20 |    13000.00 |
|            30 |    11000.00 |
|            80 |    14000.00 |
|            90 |    24000.00 |
|           100 |    12000.00 |
|           110 |    12000.00 |
+---------------+-------------+
*/

 #练习:查询部门id为10,20,30,40这4个部门中最高工资比10000高的部门信息

 非法使用聚合函数 : 不能在 WHERE 子句中使用聚合函数。如下:

SELECT department_id, AVG(salary)
FROM employees
WHERE AVG(salary) > 8000
GROUP BY department_id;
#报错:
#ERROR 1111 (HY000): Invalid use of group function

 

posted @ 2023-03-10 01:03  小林野夫  阅读(120)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/