您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

MySQL中按月统计并逐月累加统计值的几种写法

时间:2023-05-06 11:24:12  来源:今日头条  作者:

有时候,我们可能有这样的场景,需要将销量按月统计,并且按月逐月累加。写惯了GROUP BY,按月统计倒是小case,但是逐月累加实现起来,要稍微麻烦一点。下面就整理几种写法,以备不时之需。

建表及模拟数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-- 创建表
CREATE TABLE `sales` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sales_date` date NOT NULL,
  `sales_amount` decimal(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入模拟数据
INSERT INTO `sales` (`sales_date`, `sales_amount`) VALUES
('2023-01-01', 1500.00),
('2023-01-02', 1800.00),
('2023-01-05', 2200.00),
('2023-02-01', 1200.00),
('2023-02-03', 1800.00),
('2023-03-01', 2500.00),
('2023-03-05', 2800.00),
('2023-03-08', 3200.00),
('2023-04-01', 2100.00),
('2023-04-03', 1900.00),
('2023-04-05', 2600.00),
('2023-05-01', 3100.00),
('2023-05-02', 3400.00),
('2023-06-01', 3800.00),
('2023-06-06', 4200.00);

该表包含三个字段:id、sales_date、sales_amount。id为自增长主键,sales_date为销售日期,sales_amount为销售额。插入了15条模拟数据,涵盖了2023年1月至6月的销售数据

一、自连接和子查询

首先在内部查询中计算出每个月份的销售总额和月份;接着在外部查询中使用自连接和子查询计算每个月份的累计销售额

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT t1.month, t1.monthly_sales,
       SUM(t2.monthly_sales) AS cumulative_sales
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month,
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
) t1
JOIN (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month,
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
) t2 ON t1.month >= t2.month
GROUP BY t1.month;

 

二、子查询

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT month, monthly_sales,
       (SELECT SUM(monthly_sales) 
        FROM (
          SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month, SUM(sales_amount) AS monthly_sales
          FROM sales
          GROUP BY month
        ) t2
        WHERE t2.month <= t1.month) AS cumulative_sales
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month, SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
) t1;

 

此处使用了两个子查询,第一个子查询用于获取每个月份的总销售额和月份,第二个子查询用于计算累加值。在内部子查询中,通过<=操作符将当前月份以及之前所有月份的销售额相加,从而得到累加值

三、子查询+变量

1
2
3
4
5
6
7
SELECT month, monthly_sales, @cumulative := @cumulative + monthly_sales AS cumulative
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month, SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
) t1
CROSS JOIN (SELECT @cumulative := 0) t2;

 

此处使用了两个子查询,第一个子查询用于获取每个月份的总销售额和月份,第二个子查询用于初始化变量@cumulative。在外部查询中,通过CROSS JOIN将两个子查询连接起来,并且使用变量@cumulative来计算累加值。

四、用户变量和子查询

在内部查询中先对销售日期进行排序,然后使用用户变量@cumulative来记录每个月份的累加值。在最终的查询结果中,输出月份、当月销售额以及累加值

1
2
3
4
5
6
7
8
9
SELECT month, monthly_sales,
       (@cumulative := @cumulative + monthly_sales) AS cumulative_sales
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month, 
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
  ORDER BY sales_date ASC
) t1, (SELECT @cumulative := 0) t2;

 

此处使用了两个子查询,第一个子查询用于获取每个月份的总销售额和月份,并按销售日期升序排序;第二个子查询用于初始化用户变量@cumulative。在外部查询中,通过,连接两个子查询,并使用用户变量@cumulative来计算每个月份的累加值。

五、表达式(CTE)和窗口函数

使用MySQL 8.0引入的通用表表达式(CTE)和窗口函数,可以将累加值计算放在CTE中完成

1
2
3
4
5
6
7
8
9
WITH monthly_sales AS (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month, 
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
)
SELECT month, monthly_sales,
       SUM(monthly_sales) OVER (ORDER BY month) AS cumulative_sales
FROM monthly_sales;

 

此处使用了CTE来计算每个月份的总销售额和月份,并在外部查询中使用窗口函数SUM() OVER()对月份进行累加。

SUM() OVER()

使用MySQL 8.0引入的LATERAL关键字,以及OVER ORDER BY子句,按月份求和,再用SUM() OVER()进行累加,并分别输出月份、当月销售金额和累计销售金额

1
2
3
4
5
6
7
8
SELECT  month, monthly_sales,
       SUM(monthly_sales) OVER (ORDER BY month) AS cumulative_sales
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m') AS month,
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY month
) t1;

 

此处使用LATERAL关键字和OVER ORDER BY子句对每个月份进行分组,并计算每个月份的销售总额和sum() over()

目前大概就知道这几种方式,各位有没有其他更好的方法呢?



Tags:MySQL   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
有时候,我们可能有这样的场景,需要将销量按月统计,并且按月逐月累加。写惯了GROUP BY,按月统计倒是小case,但是逐月累加实现起来,要稍微麻烦一点。下面就整理几种写法,以备不时之...【详细内容】
2023-05-06  Tags: MySQL  点击:(0)  评论:(0)  加入收藏
流行数据库系统 MySQL 的新老用户常常会对数据库处理时间值的方式感到困惑。有时用户不会费心去了解时间值的数据类型。这可能是因为他们觉得本身也没有什么好了解的。日期...【详细内容】
2023-05-04  Tags: MySQL  点击:(5)  评论:(0)  加入收藏
一、 前言导读 TiDB作为NewSQL,其在对MySQL(SQL92协议)的兼容上做了很多,MySQL作为当下使用较广的事务型数据库,在IT界尤其是互联网间使用广泛,那么对于开发人员来说,1)两个数据库产...【详细内容】
2023-04-17  Tags: MySQL  点击:(25)  评论:(0)  加入收藏
1、整体介绍对于 select * from table 中的星号,我们再熟悉不过了:它告诉 MySQL 返回表所有字段的内容。MySQL 服务端收到 select 语句之后,会在 server 层把星号展开为表中的...【详细内容】
2023-04-17  Tags: MySQL  点击:(25)  评论:(0)  加入收藏
1 MySQL 常见查询技巧查看MYSQL正在运行中的进程:show processlist; 查看Mysql占用空间大小:show table status from some_database;使用示例: Mysql日期模糊查询使用:date_form...【详细内容】
2023-04-13  Tags: MySQL  点击:(16)  评论:(0)  加入收藏
之前松哥写过一个 MySQL 系列,但是当时是基于 MySQL5.7 的,最近有空在看 MySQL8 的文档,发现和 MySQL5.7 相比还是有不少变化,同时 MySQL 又是小伙伴们在面试时一个非常重要的知...【详细内容】
2023-04-13  Tags: MySQL  点击:(14)  评论:(0)  加入收藏
什么是游标?游标(cursor)是一个存储在MySQL服务器上的数据库查询, 它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游 标之后,应用程序可以根据需要滚动或浏览其中...【详细内容】
2023-04-13  Tags: MySQL  点击:(21)  评论:(0)  加入收藏
批量更新一般在批处理系统或者定时任务中比较常见,常见的诉求就是对表中多条数据进行更新(待更新的值是不一样的,这个区别于update ... where in(...))1.利用case ... when ......【详细内容】
2023-04-12  Tags: MySQL  点击:(18)  评论:(0)  加入收藏
关系型数据库还有一个重要的概念:Join(连接)。使用Join有好处,也会坏处,只有我们明白了其中的原理,才能更多的使用Join。切记不可以:业务之上,再复杂的查询也在一个连表语句中完成。...【详细内容】
2023-04-12  Tags: MySQL  点击:(16)  评论:(0)  加入收藏
一:需求背景产品签到活动需求,对于日活量不高的程序,可以直接使用MySQL去处理,当然数据量不大的话,签到一次,数据库签到表保存一条记录,也是可以的。但是如果类似京东等商城,那种签...【详细内容】
2023-04-11  Tags: MySQL  点击:(19)  评论:(0)  加入收藏
▌简易百科推荐
有时候,我们可能有这样的场景,需要将销量按月统计,并且按月逐月累加。写惯了GROUP BY,按月统计倒是小case,但是逐月累加实现起来,要稍微麻烦一点。下面就整理几种写法,以备不时之...【详细内容】
2023-05-06    今日头条  Tags:MySQL   点击:(0)  评论:(0)  加入收藏
流行数据库系统 MySQL 的新老用户常常会对数据库处理时间值的方式感到困惑。有时用户不会费心去了解时间值的数据类型。这可能是因为他们觉得本身也没有什么好了解的。日期...【详细内容】
2023-05-04    Linux中国  Tags:MySQL   点击:(5)  评论:(0)  加入收藏
1、整体介绍对于 select * from table 中的星号,我们再熟悉不过了:它告诉 MySQL 返回表所有字段的内容。MySQL 服务端收到 select 语句之后,会在 server 层把星号展开为表中的...【详细内容】
2023-04-17  一树一溪  微信公众号  Tags:MySQL   点击:(25)  评论:(0)  加入收藏
1 MySQL 常见查询技巧查看MYSQL正在运行中的进程:show processlist; 查看Mysql占用空间大小:show table status from some_database;使用示例: Mysql日期模糊查询使用:date_form...【详细内容】
2023-04-13  程序猿怪咖  今日头条  Tags:MySQL   点击:(16)  评论:(0)  加入收藏
边缘计算在有效实现机器学习、人工智能、物联网和深度学习等几个嵌入式应用程序方面发挥着至关重要的作用。 随着各行业组织在日常运营中越来越依赖数据,企业应该在哪里存储...【详细内容】
2023-04-13  e-works  微信公众号  Tags:边缘计算   点击:(22)  评论:(0)  加入收藏
边缘计算已经席卷了IT行业。在疫情期间,各企业迅速扩展了边缘网络,将新的计算能力放在了用户附近。边缘站点使企业能够仅部署他们需要的容量、在本地处理数据和进行实时分析,减...【详细内容】
2023-04-13    千家网  Tags:数据中心   点击:(16)  评论:(0)  加入收藏
之前松哥写过一个 MySQL 系列,但是当时是基于 MySQL5.7 的,最近有空在看 MySQL8 的文档,发现和 MySQL5.7 相比还是有不少变化,同时 MySQL 又是小伙伴们在面试时一个非常重要的知...【详细内容】
2023-04-13  江南一点雨  微信公众号  Tags:MySQL   点击:(14)  评论:(0)  加入收藏
什么是游标?游标(cursor)是一个存储在MySQL服务器上的数据库查询, 它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游 标之后,应用程序可以根据需要滚动或浏览其中...【详细内容】
2023-04-13  SQL数据库开发  微信公众号  Tags:MySQL   点击:(21)  评论:(0)  加入收藏
批量更新一般在批处理系统或者定时任务中比较常见,常见的诉求就是对表中多条数据进行更新(待更新的值是不一样的,这个区别于update ... where in(...))1.利用case ... when ......【详细内容】
2023-04-12  Running的程序员  今日头条  Tags:MySQL   点击:(18)  评论:(0)  加入收藏
关系型数据库还有一个重要的概念:Join(连接)。使用Join有好处,也会坏处,只有我们明白了其中的原理,才能更多的使用Join。切记不可以:业务之上,再复杂的查询也在一个连表语句中完成。...【详细内容】
2023-04-12  做好一个程序猿  今日头条  Tags:MySQL   点击:(16)  评论:(0)  加入收藏
站内最新
站内热门
站内头条