MySQL学习笔记(四)—— 聚合(分组)函数

1. 两种 SQL 函数

image-20221030213531251

2. 聚合函数简介

  • 聚合(或聚集、分组)函数,它是对一组数据进行汇总的函数,输入的是一组数据的集合,输出的是单个值。

image-20221031211850873

  • 聚合函数类型

    • AVG()
    • SUM()
    • MAX()
    • MIN()
    • COUNT()
  • 语法格式

    SELECT cloumn1, group function(cloumn2)
    FROM table
    WHERE condition
    GROUP BY cloumn2
    ORDER BY cloumn2;
    
  • 分组函数自动忽略NULL

  • 分组函数不能直接使用在where子句中

  • 所有的分组函数可以组合起来一起用

3. 常见的几种聚合函数

3.1 AVG 和 SUM 函数

  • 可以对数值型数据使用AVG 和 SUM 函数。
  • AVG 与 SUM 函数会过滤空值
SELECT AVG(salary), MAX(salary),MIN(salary), SUM(salary)
FROM employees
WHERE job_id LIKE '%REP%';

image-20221031213438958

3.2 MIN 和 MAX 函数

  • 可以对任意数据类型的数据使用 MIN 和 MAX 函数。
  • MIN 和 MAX 函数会过滤空值

3.3 COUNT 函数

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

SELECT COUNT(*)
FROM employees
WHERE department_id = 50;

image-20221031213607872

  • count(*),count(1),count(列名) 用谁好?*
    • 对于MyISAM引擎的表是没有区别的。这种引擎内部有一计数器在维护着行数。三者效率相同,都是O(1)
    • Innodb引擎的表用count(*),count(1)直接读行数,复杂度是O(n),因为innodb真的要去数一遍。但好于具体的count(列名)。三者效率:COUNT(*) = COUNT(1)> COUNT(字段)
  • 能不能用 count(列名) 替换 count(*)
    • 不要使用 count(列名)来替代 count(*) , count(*) 是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
    • 说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

4. GROUP BY

#需求:查询各个部门的平均工资,最高工资
SELECT department_id,AVG(salary),SUM(salary)
FROM employees
GROUP BY department_id
  • 结论1 :SELECT中出现的非组函数的字段必须声明在GROUP BY 中。反之,GROUP BY中声明的字段可以不出现在SELECT中
  • GROUP BY 声明在FROM后面、WHERE后面,ORDER BY 前面、LIMIT前面

5. HAVING

  1. 如果过滤条件中使用了聚合函数,则必须使用HAVING来替换WHERE。否则,报错。

  2. HAVING 必须声明在 GROUP BY 的后面

  3. 开发中,我们使用HAVING的前提是SQL中使用了GROUP BY。即:HAVING 不能单独使用,必须要跟 GROUP BY 一起使用

  4. 结论:

    • 当过滤条件中有聚合函数时,则此过滤条件必须声明在HAVING中

    • 当过滤条件中没有聚合函数时,则此过滤条件声明在WHERE中或HAVING中都可以。但是,建议大家声明在WHERE中

  5. WHERE 与 HAVING 的对比

  • 从适用范围上来讲,HAVING的适用范围更广。
  • 如果过滤条件中没有聚合函数:这种情况下,WHERE的执行效率要高于HAVING

6. SQL 底层执行原理

6.1 SELECT 语句的完整结构

#方式1:sql92语法
SELECT ...,....,...
FROM ...,...,....
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

#方式2:sql99语法
SELECT ...,....,...
FROM ... JOIN ...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...

#其中:
#(1)from:从哪些表中筛选
#(2)on:关联多表查询时,去除笛卡尔积
#(3)where:从表中筛选的条件
#(4)group by:分组依据
#(5)having:在统计结果中再次筛选
#(6)order by:排序
#(7)limit:分页

6.2 关键字的编写顺序

# 严格执行,不能颠倒,需要记忆
SELECT 
	... 
FROM
	... 
WHERE
	... 
GROUP BY
	... 
HAVING
	... 
ORDER BY
	... 
LIMIT
	...

6.3 SELECT语句的执行顺序

  • 在 MySQL 和 Oracle 中,SELECT 执行顺序基本相同
# 详细
FROM ...,...-> ON -> (LEFT/RIGNT  JOIN) -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT(去重) -> ORDER BY -> LIMIT

# 执行顺序
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT 的字段 -> DISTINCT(去重) -> ORDER BY -> LIMIT

参考

https://www.bilibili.com/video/BV1iq4y1u7vj/?spm_id_from=333.337.search-card.all.click&vd_source=25b05e9bd8b4bdac16ca2f47bbeb7990

猜你喜欢

转载自blog.csdn.net/qq_42130468/article/details/127640684