服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - MySQL中按月统计并逐月累加统计值的几种写法

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

2023-05-07 01:00未知服务器之家 Mysql

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

有时候,我们可能有这样的场景,需要将销量按月统计,并且按月逐月累加。写惯了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;


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

二、子查询


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;


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

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

三、子查询+变量


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;


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

此处使用了两个子查询,第一个子查询用于获取每个月份的总销售额和月份,第二个子查询用于初始化变量@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;


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

此处使用了两个子查询,第一个子查询用于获取每个月份的总销售额和月份,并按销售日期升序排序;第二个子查询用于初始化用户变量@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;


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

此处使用了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;


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

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

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

延伸 · 阅读

精彩推荐
  • Mysql解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起...

    Veir_dev5592019-06-25
  • MysqlERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event(): read error, data_len: 438, event_type: 2 ...

    MYSQL教程网6412020-03-13
  • Mysqlmysql 不能插入中文问题

    mysql 不能插入中文问题

    当向mysql5.5插入中文时,会出现类似错误 ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column ...

    MYSQL教程网5722019-11-25
  • Mysql浅谈mysql 树形结构表设计与优化

    浅谈mysql 树形结构表设计与优化

    在诸多的管理类,办公类等系统中,树形结构展示随处可见,本文主要介绍了mysql 树形结构表设计与优化,具有一定的参考价值,感兴趣的小伙伴们可以参...

    小码农叔叔5242021-11-16
  • MysqlMySQL锁的知识点总结

    MySQL锁的知识点总结

    在本篇文章里小编给大家整理了关于MySQL锁的知识点总结以及实例内容,需要的朋友们学习下。...

    别人放弃我坚持吖4362020-12-14
  • MysqlMySQL数据库varchar的限制规则说明

    MySQL数据库varchar的限制规则说明

    本文我们主要介绍了MySQL数据库中varchar的限制规则,并以一个实际的例子对限制规则进行了说明,希望能够对您有所帮助。 ...

    mysql技术网4192019-11-23
  • MysqlMySQL 数据备份与还原的示例代码

    MySQL 数据备份与还原的示例代码

    这篇文章主要介绍了MySQL 数据备份与还原的相关知识,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    逆心2972019-06-23
  • Mysql详解MySQL中的分组查询与连接查询语句

    详解MySQL中的分组查询与连接查询语句

    这篇文章主要介绍了MySQL中的分组查询与连接查询语句,同时还介绍了一些统计函数的用法,需要的朋友可以参考下 ...

    GALAXY_ZMY5442020-06-03