MySQL 必知必会
朱晓峰
前摩根大通银行技术部副总裁、系统架构师
17746 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
MySQL 必知必会
15
15
1.0x
00:00/00:00
登录|注册

08 | 聚合函数:怎么高效地进行分组统计?

你好,我是朱晓峰。今天,我来和你聊一聊聚合函数。
MySQL 中有 5 种聚合函数较为常用,分别是求和函数 SUM()、求平均函数 AVG()、最大值函数 MAX()、最小值函数 MIN() 和计数函数 COUNT()。接下来,我就结合超市项目的真实需求,来带你掌握聚合函数的用法,帮你实现高效的分组统计。
咱们的项目需求是这样的:超市经营者提出,他们需要统计某个门店,每天、每个单品的销售情况,包括销售数量和销售金额等。这里涉及 3 个数据表,具体信息如下所示:
销售明细表(demo.transactiondetails):
销售单头表(demo.transactionhead):
商品信息表(demo.goodsmaster):
要统计销售,就要用到数据求和,那么我们就先来学习下求和函数 SUM()。

SUM()

SUM()函数可以返回指定字段值的和。我们可以用它来获得用户某个门店,每天,每种商品的销售总计数据:
mysql> SELECT
-> LEFT(b.transdate, 10), -- 从关联表获取交易时间,并且通过LEFT函数,获取交易时间字符串的左边10个字符,得到年月日的数据
-> c.goodsname, -- 从关联表获取商品名称
-> SUM(a.quantity), -- 数量求和
-> SUM(a.salesvalue) -- 金额求和
-> FROM
-> demo.transactiondetails a
-> JOIN
-> demo.transactionhead b ON (a.transactionid = b.transactionid)
-> JOIN
-> demo.goodsmaster c ON (a.itemnumber = c.itemnumber)
-> GROUP BY LEFT(b.transdate, 10) , c.goodsname -- 分组
-> ORDER BY LEFT(b.transdate, 10) , c.goodsname; -- 排序
+-----------------------+-----------+-----------------+-------------------+
| LEFT(b.transdate, 10) | goodsname | SUM(a.quantity) | SUM(a.salesvalue) |
+-----------------------+-----------+-----------------+-------------------+
| 2020-12-01 || 2.000 | 178.00 |
| 2020-12-01 || 5.000 | 25.00 |
| 2020-12-02 || 4.000 | 356.00 |
| 2020-12-02 || 16.000 | 80.00 |
+-----------------------+-----------+-----------------+-------------------+
4 rows in set (0.01 sec)
可以看到,我们引入了 2 个关键字:LEFT 和 ORDER BY,你可能对它们不熟悉,我来具体解释下。
LEFT(str,n):表示返回字符串 str 最左边的 n 个字符。我们这里的 LEFT(a.transdate,10),表示返回交易时间字符串最左边的 10 个字符。在 MySQL 中,DATETIME 类型的默认格式是:YYYY-MM-DD,也就是说,年份 4 个字符,之后是“-”,然后是月份 2 个字符,之后又是“-”,然后是日 2 个字符,所以完整的年月日是 10 个字符。用户要求按照日期统计,所以,我们需要从日期时间数据中,把年月日的部分截取出来。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

聚合函数在MySQL中有着广泛的应用,包括求和函数SUM()、平均函数AVG()、最大值函数MAX()、最小值函数MIN()和计数函数COUNT()。本文通过超市项目的实际需求,结合示例代码,详细介绍了这些聚合函数的用法和执行步骤。通过示例代码演示了如何使用SUM()函数进行分组统计,以及使用LEFT和ORDER BY关键字进行数据处理和排序。此外,还介绍了AVG()、MAX()和MIN()函数的使用方法,以及需要注意的细节,如AVG()函数计算平均值,MAX()和MIN()函数获取分组中的最大值和最小值。总结来说,本文通过实际案例和详细的示例代码,帮助读者快速了解了聚合函数的高效使用方法,对于需要进行分组统计的数据处理具有很好的参考价值。 在实际应用中,COUNT()函数可以用于统计数据集的大小,对系统优化十分重要。通过分页策略结合COUNT()函数,可以提高系统响应速度。COUNT()函数有两种情况,COUNT(*)用于统计记录数,而COUNT(字段)用于统计字段值不为空的次数。通过示例代码演示了如何利用COUNT()函数对分组数据进行统计,以及如何利用COUNT(字段)统计字段值不为空的次数。此外,文章还提到了聚合函数可以和其他关键字、函数一起使用,拓展了它们的使用场景,让原本复杂的计算变得简单。最后,文章提出了一个思考题,引发读者思考和讨论。 通过本文的总结,读者可以快速了解聚合函数在MySQL中的应用,以及COUNT()函数在系统优化和数据统计中的重要性,同时也能够了解到聚合函数的灵活性和与其他关键字、函数的组合应用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 必知必会》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(17)

  • 最新
  • 精选
  • 朱晓峰
    置顶
    你好,我是朱晓峰,下面我就来公布一下上节课思考题的答案: 上节课,我们学习了条件语句WHERE和HAVING。下面是思考题的参考答案: HAVING后面的条件,必须是包含分组中计算函数的条件。这种说法是有道理的,主要是考虑到查询的效率。因为如果不是分组中的计算函数的条件,那么这个条件应该可以用WHERE而不是用HAVING,查询的效率就不高了。
    2021-04-21
    16
  • 海林Lin
    思考题答案: SELECT goodsname, count(goodsname) FROM demo.goodsmaster GROUP BY goodsname HAVING count(goodsname) > 1;

    作者回复: 请参考公布的思考题答案

    2021-04-05
    5
  • 右耳朵猫咪
    像sum()、avg()这样的函数都是统计非空的记录;文章中对group by后的字段做了函数处理,会降低性能,实际开发中不会这么搞。

    作者回复: 还是要根据实际场景分析

    2021-03-25
    4
    5
  • Michael
    我一直有个疑惑就是当我需要做对某些字段做group by来分组 我可能还需要其他不作为group by的字段 但是根据SQL标准 出现在select后面的字段要么是group by里的字段 要么是聚合函数 那么这种情况应该怎么处理呢?

    作者回复: 既然分组,自然就会只用到分组字段和组内的计算,如果你还要用到其他字段,应该是你这个查询的需求还没有分析好

    2021-03-25
    5
    4
  • giteebravo
    如何像老师一样分析出这些个聚合函数分组统计的步骤?

    作者回复: 多做项目多实践,熟能生巧

    2021-03-29
    2
  • 之墨
    老师请教一个问题,一个必录字段在前端已经做了必录校验,还有必要在mysql数据库勾上不能为null的校验吗?为什么呢?

    作者回复: 非常有必要。原因是前端的代码经常会有改动,为了确保数据的正确性,在数据表设计的时候,加上不能为空的校验是很有好处的。

    2021-12-03
    2
    1
  • 上邪忘川
    老师你好,每次有新表的时候,可否贴一下建表语句和插入的数据

    作者回复: 这样可能会占用较大的篇幅,不够紧凑

    2021-03-31
    3
    1
  • Kansei
    老师能说说count(*) ,count(1) ,count(列名),这3者的区别吗?

    作者回复: count(*) 意思是统计表中所有的行 count(1) 意思是统计表的行数 count(列名)意思是统计表中列名字段不为NULL的数量 在MySQL中,count(*)和count(1)没什么区别,count(列名)不会把列名字段值为NULL的统计进去

    2021-03-26
    4
    1
  • 王睿
    胃还可以哈,都消化吸收了

    作者回复: 多做实操,加深理解

    2022-04-07归属地:广东
  • 火车日记
    count(*) 和count(1)或count(字段)哪个效率高呢?

    作者回复: count(*)与count(1)差别不大,count(1)稍微高效一点。count(字段)时,如果字段是主键,那么count(字段)更快,否则count(*),count(1)更快一些

    2022-02-04
    2
收起评论
显示
设置
留言
17
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部