目录

聚合函数(组函数)

GROUP BY

查询总结


聚合函数(组函数)

  • 什么是聚合函数

聚合函数作用于一组数据,并对一组数据返回一个值。

group by 聚合函数数组转string mysql 聚合函数和group by_数据


聚合函数类型 :  AVG()、 SUM()、  MAX()、 MIN()、 COUNT()



  • 聚合函数语法

group by 聚合函数数组转string mysql 聚合函数和group by_mysql_02


注:Mysql中聚合函数无法嵌套使用

  • AVGSUM函数 (平均数、总和)

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

group by 聚合函数数组转string mysql 聚合函数和group by_聚合函数_03

  • MINMAX函数 (最小、最大值)

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

group by 聚合函数数组转string mysql 聚合函数和group by_sql_04

  • COUNT函数

COUNT(*)返回表中记录总数,适用于任意数据类型

group by 聚合函数数组转string mysql 聚合函数和group by_sql_05

COUNT(expr) 返回expr不为空的记录总数。

group by 聚合函数数组转string mysql 聚合函数和group by_mysql_06

#需求:查询公司中平均奖金率
#错误的!
SELECT AVG(commission_pct)    #AVG()与COUNT(列)不会统计空值
FROM employees;

#正确的:
SELECT SUM(commission_pct) / COUNT(*),
AVG(IFNULL(commission_pct,0))
FROM employees;

问题1:用 count(*) count(1) count( 列名 ) 谁好呢 ?

其实,对于 MyISAM 引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。

Innodb 引擎的表用 count(*),count(1) 直接读行数,复杂度是 O(n) ,因为 innodb 真的要去数一遍。但好 于具体的count( 列名 )



问题2:能不能使用 count( 列名 ) 替换 count(*)?

不要使用 count( 列名 ) 来替代 count(*) , count(*) 是 SQL92 定义的标准统计行数的语法,跟数 据库无关,跟 NULL 和非 NULL 无关。

说明:count(*) 会统计值为 NULL 的行,而 count( 列名 ) 不会统计此列为 NULL 值的行。


GROUP BY

可以使用GROUP BY子句将表中的数据分成若干组

#分组时可以有多个分组字段

group by 聚合函数数组转string mysql 聚合函数和group by_sql_07




group by 聚合函数数组转string mysql 聚合函数和group by_mysql_08


出现在SELECT列表中的列都应该包含在 GROUP BY子句中 ,否则该列没有参考价值


  • 多个列分组

group by 聚合函数数组转string mysql 聚合函数和group by_mysql_09

  • GROUP BY 中使用 WITH ROLLUP


group by 聚合函数数组转string mysql 聚合函数和group by_mysql_10


#需求:查询各个部门的平均工资,按照平均工资升序排列
SELECT department_id,AVG(salary) avg_sal
FROM employees
GROUP BY department_id
ORDER BY avg_sal ASC;


#分组时可以有多个分组字段
-- 每一个人的部门编号 工作编号 薪资
select ename,did,job_id from t_employee; 
-- 统计 不同部门不同工作的 平均薪资 最高薪资 人数
select e.`did`,e.`job_id`,avg(salary),max(salary),count(*)
from t_employee e
group by e.`did`,e.`job_id`;


HAVING(替代where)

由于不能在 WHERE 子句中使用聚合函数


过滤分组: HAVING 子句


1. 行已经被分组。


2. 使用了聚合函数


3. 满足 HAVING 子句中条件的分组将被显示。


4. HAVING 不能单独使用,必须要跟 GROUP BY 一起使用。


 

group by 聚合函数数组转string mysql 聚合函数和group by_数据_11

 WHERE 与 HAVING 

group by 聚合函数数组转string mysql 聚合函数和group by_sql_12

开发中的选择:

WHERE 和 HAVING 也不是互相排斥的,我们可以在一个查询里面同时使用 WHERE 和 HAVING 。包含分组 统计函数的条件用 HAVING ,普通条件用 WHERE 。这样,我们就既用了 WHERE 条件的高效快速,又发 挥了 HAVING 可以使用包含分组统计函数的查询条件的优点。当数据量特别大的时候,运行效率会有很 大的差别。

查询总结

  • SELECT 语句的完整结构
#4. SQL底层执行原理
#4.1 SELECT 语句的完整结构
/*

#sql99语法:
SELECT ....,....,....(存在聚合函数)
FROM ... (LEFT / RIGHT)JOIN ....ON 多表的连接条件 
(LEFT / RIGHT)JOIN ... ON ....
WHERE 不包含聚合函数的过滤条件
GROUP BY ...,....
HAVING 包含聚合函数的过滤条件
ORDER BY ....,...(ASC / DESC )
LIMIT ...,....

#sql92语法:
SELECT ....,....,....(存在聚合函数)
FROM ...,....,....
WHERE 多表的连接条件 AND 不包含聚合函数的过滤条件
GROUP BY ...,....
HAVING 包含聚合函数的过滤条件
ORDER BY ....,...(ASC / DESC )
LIMIT ...,....

*/

SELECT执行顺序

group by 聚合函数数组转string mysql 聚合函数和group by_数据_13

#4.2 SQL语句的执行过程:
#FROM ...,...-> ON -> (LEFT/RIGNT  JOIN) -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> 
# ORDER BY -> LIMIT