MySQL里怎么查这段时间和之前那段时间的数据,感觉挺常用的吧
- 问答
- 2026-01-05 07:43:07
- 16
这个需求确实非常常见,比如我们经常想看看“这个月和上个月的销售额对比”,或者“本周和上周的用户活跃数”,在MySQL里,实现这个目标的核心思路就是巧妙地运用WHERE子句来筛选出两个时间范围的数据,然后通过一些技巧把它们放在一起方便比较。
最直接了当的方法就是使用BETWEEN ... AND ...或者简单的比较运算符(>=, <)来定义时间范围,假设我们有一张销售表sales,里面有一个日期字段sale_date。
分别查询,然后手动合并对比
这是最朴素的方法,适合快速看一眼数据,你只需要写两条查询语句。
-
查询“这段时间”的数据(本月):
SELECT SUM(amount) AS 本月销售额 FROM sales WHERE sale_date BETWEEN '2023-10-01' AND '2023-10-31';这里,BETWEEN '2023-10-01' AND '2023-10-31'精确地圈定了十月份的数据。 -
查询“之前那段时间”的数据(上个月):
SELECT SUM(amount) AS 上月销售额 FROM sales WHERE sale_date BETWEEN '2023-09-01' AND '2023-09-30';
你分别执行这两条语句,就能得到两个数字,然后自己心里或者在本子上做个对比,这种方法的好处是简单明了,一看就懂,缺点是如果需要比较的指标很多,或者需要经常做这种对比,每次都写两条语句并手动计算增长率什么的就很麻烦。

使用UNION ALL将两段时间的数据上下堆叠起来
如果我们希望一条SQL语句就能同时看到两个时间段的结果,让结果更清晰,可以用UNION ALL,它能把两条查询的结果上下拼接在一起。
SELECT ‘本月’ AS 时间段, SUM(amount) AS 总销售额 FROM sales WHERE sale_date BETWEEN ‘2023-10-01’ AND ‘2023-10-31’ UNION ALL SELECT ‘上月’ AS 时间段, SUM(amount) AS 总销售额 FROM sales WHERE sale_date BETWEEN ‘2023-09-01’ AND ‘2023-09-30’;
这条语句执行后,会返回一个两行的结果: 时间段 | 总销售额 --- | --- 本月 | 100000 上月 | 90000
这样对比起来就一目了然了,你还可以在每条SELECT语句里添加更多的统计项,比如平均销售额、订单数等,只要两个SELECT语句的列数和类型对应上就行。

使用条件聚合(CASE WHEN)将两段时间的数据左右并列
有时候我们更喜欢并排对比,就像Excel表格一样,本月一列,上月一列,这时候CASE WHEN语句就派上用场了,它可以在一个查询里,根据不同的条件对数据进行分类统计。
SELECT SUM(CASE WHEN sale_date BETWEEN ‘2023-10-01’ AND ‘2023-10-31’ THEN amount ELSE 0 END) AS 本月销售额, SUM(CASE WHEN sale_date BETWEEN ‘2023-09-01’ AND ‘2023-09-30’ THEN amount ELSE 0 END) AS 上月销售额 FROM sales;
这条语句的逻辑是:扫描整个sales表,当遇到日期属于10月份的记录时,就把它的amount值累加到“本月销售额”这个虚拟列里;遇到9月份的记录,就累加到“上月销售额”里;其他日期的记录,因为ELSE 0,所以加了个0,不影响结果。
最终输出只有一行数据: 本月销售额 | 上月销售额 --- | --- 100000 | 90000

这种并列的方式在进行计算时特别方便,比如你可以直接在选择列里写公式计算增长率:(本月销售额 - 上月销售额) / 上月销售额 AS 增长率。
让时间范围动态化(避免硬编码)
上面例子中的日期‘2023-10-01’这些都是写死的,我们称之为“硬编码”,在实际工作中,我们肯定不希望每个月都要去改SQL语句,MySQL提供了一些很有用的日期函数来帮助我们动态获取时间范围。
- 获取当前日期:
CURDATE() - 获取本月的第一天:
DATE_FORMAT(CURDATE(), ‘%Y-%m-01’) - 获取上个月的第一天:
DATE_SUB(DATE_FORMAT(CURDATE(), ‘%Y-%m-01’), INTERVAL 1 MONTH) - 获取某个月的最后一天:
LAST_DAY(‘2023-10-01’)会返回 ‘2023-10-31’
把这些函数组合起来,我们就可以写出动态的查询,无论哪天运行,都能正确查出“本月”和“上月”数据的语句:
SELECT SUM(CASE WHEN sale_date >= DATE_FORMAT(CURDATE(), ‘%Y-%m-01’) AND sale_date <= LAST_DAY(CURDATE()) THEN amount ELSE 0 END) AS 本月销售额, SUM(CASE WHEN sale_date >= DATE_SUB(DATE_FORMAT(CURDATE(), ‘%Y-%m-01’), INTERVAL 1 MONTH) AND sale_date <= LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) THEN amount ELSE 0 END) AS 上月销售额 FROM sales;
这个语句看起来复杂,但核心思想就是把之前写死的日期字符串,替换成了能自动计算当前月初、上个月初、当前月末、上个月末的日期函数表达式,这样查询就变得智能和通用了。
总结一下
查询和对比不同时间段的数据,关键在于灵活运用WHERE子句划定范围,并根据你的展示需求(是想上下堆叠还是左右并列)选择使用UNION ALL或者CASE WHEN,更进一步,用MySQL的日期函数(如CURDATE, DATE_SUB, LAST_DAY)代替硬编码的日期,能让你的查询脚本一劳永逸,这些方法组合起来,就能很好地应对这种非常常见的业务分析需求。
本文由帖慧艳于2026-01-05发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/74823.html
