【MySQL】08:聚合函数

08:聚合函数

什么是聚合函数?

聚合函数是输入一组值,返回一个值的函数。
可以理解为以下的图片:
在这里插入图片描述

常见的聚合函数

  • AVG 平均值/SUM 总和

    这两个函数只可以传递数值类型。

    SELECT AVG(salary),SUM(salary)/107
    FROM employees
    
  • MAX 最大值/MIN 最小值

    这两个函数可以传递数值、字符串、日期等多种类型。

    SELECT MIN(last_name),MAX(last_name),MAX(salary)
    FROM employees
    
  • COUNT 计算指定字段在表中出现的次数。
    例一:计算表中的所有字段出现的次数:

    SELECT COUNT(*),COUNT(1)
    FROM employees
    
    # 不推荐使用 COUNT(字段名)——因为这样计算会自动忽略NULL值。
    

    例二:计算平均值:SUM / COUNT = AVG

    # 计算commission_pct的平均值。commission_pct存在NULL值。
    SELECT SUM(commission_pct)/COUNT(IFNULL(commission_pct,1)),AVG(IFNULL(commission_pct,0))
    FROM employees
    

如何需要统计表中的记录数,使用COUNT()、COUNT(1)、COUNT(具体字段) 哪个效率更高呢?
如果使用的是MyISAM 存储引擎,则三者效率相同,都是O(1)
如果使用的是InnoDB 存储引擎,则三者效率:COUNT(
) = COUNT(1)> COUNT(字段)

  • GROUP BY 对数据进行分组
    例一:查询每个部门的平均工资。要使用GROUP BY将各个部门进行分组。

    SELECT department_id,AVG(salary)
    FROM employees
    GROUP BY department_id
    

    例二:查询每个部门并且同一工种的平均工资。要使用GROUP BY将各个部门中的各个工种进行多重分组。

    SELECT department_id,job_id,AVG(salary)
    FROM employees
    GROUP BY department_id,job_id
    

    注意:
    一:SELECT中出现的非组(聚合)函数的字段必须声明在GROUP BY 中。如例二。
    反之,GROUP BY中声明的字段可以不出现在SELECT中

    二:GROUP BY 声明在FROM后面、WHERE后面,ORDER BY 前面、LIMIT前面。

    三:GROUP BY中使用WITH ROLLUP,显示最后一条记录会不分组进行汇总。

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

  • HAVING 过滤分组

  1. HAVING要在GROUP BY 之后使用
  2. 已经使用了聚合函数时,要用HAVING
  3. HAVING不单独使用,和GROUP BY 一起使用
    例一:查询各个部门中最高工资比10000高的部门信息
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000

WHERE和HAVING的区别:

  1. WHERE可以使用表中的字段作为筛选条件,但不能使用聚合函数作为筛选条件。HAVING必须与GROP BY配合使用,可以把聚合函数作为筛选条件。
  2. 直接使用表中的字段作为筛选条件时,使用WHERE要优于HAVING。因为WHERE执行顺序优于HAVING,先筛选数据在进行GROUP UP。这样可以用一个较小的数据集进行分组。提高效率。

SELECT的执行过程

SELECT ...,... #5
FROM ... JOIN ... #1
ON 多表的连接条件  
JOIN ...         
ON ...           
WHERE 不包含组函数的过滤条件 #2
GROUP BY ... #3
HAVING 包含组函数的过滤条件 #4
ORDER BY ... ASC/DESC #6
LIMIT ...,...   #7

执行过程:

FROM ...,...-> ON -> 
(LEFT/RIGNT  JOIN) -> 
WHERE -> 
GROUP BY -> HAVING -> 
SELECT -> DISTINCT(去重) -> 
ORDER BY -> LIMIT
  • SQL的执行原理

FROM
SELECT 是先执行 FROM 这一步的。在这个阶段,如果是多张表联查,还会经历下面的几个步骤:

  1. 首先先通过 CROSS JOIN 求笛卡尔积,相当于得到虚拟表 vt(virtual table)1-1;
  2. 通过 ON 进行筛选,在虚拟表 vt1-1 的基础上进行筛选,得到虚拟表 vt1-2;
  3. 添加外部行。如果我们使用的是左连接、右链接或者全连接,就会涉及到外部行,也就是在虚拟表 vt1-2 的基础上增加外部行,得到虚拟表 vt1-3。

当然如果我们操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得到是我们的原始数据。
WHERE
当我们拿到了查询数据表的原始数据,也就是最终的虚拟表 vt1 ,就可以在此基础上再进行 WHERE 阶段 。在这个阶段中,会根据 vt1 表的结果进行筛选过滤,得到虚拟表 vt2 。
GROUP–>HAVING
然后进入第三步和第四步,也就是 GROUPHAVING 阶段 。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3 和 vt4 。
SELECT
当我们完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT 阶段 。
首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表vt5-1 和 vt5-2 。
ORDER BY
当我们提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段 ,得到虚拟表 vt6 。
LIMIT
最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段 ,得到最终的结果,对应的是虚拟表vt7 。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sivan_Xin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值