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

 更新时间:2023年10月31日 15:33:52   作者:高级盘丝洞  
有时候,我们可能有这样的场景,需要将销量按月统计,并且按月逐月累加,本文就来介绍一下MySQL中按月统计并逐月累加统计值的几种实现写法,感兴趣的可以了解一下

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

本月第一天

-- 本月第一天
SELECT DATE_ADD(CURDATE(), INTERVAL -DAY(CURDATE()) + 1 DAY);
 
-- 本月第一天
SELECT CONCAT(DATE_FORMAT(CURDATE(), '%Y-%m'), '-01');

建表及模拟数据

-- 创建表
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月的销售数据

一、自连接和子查询

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

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;

二、子查询

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;

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

三、子查询+变量

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来记录每个月份的累加值。在最终的查询结果中,输出月份、当月销售额以及累加值

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中完成

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()进行累加,并分别输出月份、当月销售金额和累计销售金额

##月统计
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;

##日统计
SELECT  day, monthly_sales,
       SUM(monthly_sales) OVER (ORDER BY day) AS cumulative_sales
FROM (
  SELECT DATE_FORMAT(sales_date, '%Y-%m-%d') AS day,
         SUM(sales_amount) AS monthly_sales
  FROM sales
  GROUP BY day
) t1;

到此这篇关于MySQL中按月统计并逐月累加统计值的几种实现写法的文章就介绍到这了,更多相关MySQL 按月统计并逐月累加内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • CentOS7下安装MySQL5.7.39的详细过程

    CentOS7下安装MySQL5.7.39的详细过程

    这篇文章主要介绍了CentOS7下安装MySQL5.7.39的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • MySQL的一些常用的SQL语句整理

    MySQL的一些常用的SQL语句整理

    这篇文章主要介绍了MySQL的一些常用的SQL语句整理,非常基础,适合随看随记:)需要的朋友可以参考下
    2015-07-07
  • MySQL数据库管理常用命令小结

    MySQL数据库管理常用命令小结

    MySQL数据库是一种开放源代码的关系型数据库管理系统,MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理,MySQL数据库管理有它自己独特的使用命令,下面为您介绍MySQL数据库管理常用命令。
    2011-03-03
  • Mysql联合查询UNION和UNION ALL的使用介绍

    Mysql联合查询UNION和UNION ALL的使用介绍

    本文详细介绍了Mysql的联合查询命令UNION和UNION ALL,总结了使用语法和注意事项,以及学习例子和项目例子,需要的朋友可以参考下
    2014-04-04
  • mysql优化limit查询语句的5个方法

    mysql优化limit查询语句的5个方法

    这篇文章主要介绍了mysql优化limit查询语句的5个方法,它们分别是子查询优化法、倒排表优化法、反向查找优化法、limit限制优化法和只查索引法,需要的朋友可以参考下
    2014-07-07
  • MySQLexplain之possible_keys、key及key_len详解

    MySQLexplain之possible_keys、key及key_len详解

    这篇文章主要介绍了MySQLexplain之possible_keys、key及key_len的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • mysql查找字符串函数的使用

    mysql查找字符串函数的使用

    这篇文章主要介绍了mysql查找字符串函数的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • mysql表的四种分区方式总结

    mysql表的四种分区方式总结

    通俗地讲表分区是将一大表,根据条件分割成若干个小表,下面这篇文章主要给大家介绍了关于mysql表的四种分区方式,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • MySQL中索引失效场景,原因以及解决方法介绍

    MySQL中索引失效场景,原因以及解决方法介绍

    这篇文章主要为大家详细介绍了MySQL中索引失效场景,原因以及解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-07-07
  • MySQL部署后连接被拒绝问题的排查与解决方法详细指南

    MySQL部署后连接被拒绝问题的排查与解决方法详细指南

    MySQL是一个开源的、关系型数据库管理系统,在开发过程中被广泛使用,有时候我们可能会遇到MySQL连接不上本地服务器的问题,这篇文章主要介绍了MySQL部署后连接被拒绝问题的排查与解决方法,需要的朋友可以参考下
    2025-11-11

最新评论