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 个字符。用户要求按照日期统计,所以,我们需要从日期时间数据中,把年月日的部分截取出来。