You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计近7个月数据(含无记录月份的0值统计)

解决近7个月数据统计(含无记录月份)的问题

问题描述

有一张包含datetime类型列created_date的数据表,需要统计近7个月的记录数,要求即使某月份没有记录,也要显示该月份并将统计数设为0。

表结构与示例数据:

id | created_date
1  | 2022-11-08
2  | 2023-02-12
3  | 2023-03-09
4  | 2023-07-02
5  | 2023-07-07
6  | 2023-07-09

原查询的问题:直接从数据表过滤分组时,没有记录的月份不会被返回,导致输出缺失部分月份。

解决方案

核心思路是先生成近7个月的完整月份列表,再通过左连接将统计结果与月份列表关联,确保所有月份都被保留。

方法1:使用CTE生成月份列表(MySQL 8.0+支持)

WITH months AS (
    -- 生成近7个月的第一个月份(当前日期往前推6个月)
    SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 6 MONTH), '%Y-%m') AS month_val
    UNION ALL
    -- 递归生成后续月份,直到当前月份
    SELECT DATE_FORMAT(DATE_ADD(month_val, INTERVAL 1 MONTH), '%Y-%m')
    FROM months
    WHERE DATE_ADD(month_val, INTERVAL 1 MONTH) <= DATE_FORMAT(CURDATE(), '%Y-%m')
)
SELECT 
    IFNULL(d.datacount, 0) AS datacount,
    MONTH(m.month_val) AS datamonth,
    m.month_val AS year_month -- 可选,显示年月避免跨年度歧义
FROM months m
-- 左连接统计结果,确保所有月份都被保留
LEFT JOIN (
    SELECT 
        COUNT(id) AS datacount,
        DATE_FORMAT(created_date, '%Y-%m') AS year_month
    FROM data
    WHERE created_date >= DATE_SUB(CURDATE(), INTERVAL 7 MONTH)
    GROUP BY year_month
) d ON m.month_val = d.year_month
ORDER BY m.month_val;

方法2:手动生成月份列表(兼容MySQL 5.x)

如果不支持CTE,可以用UNION手动列出近7个月:

SELECT 
    IFNULL(d.datacount, 0) AS datacount,
    MONTH(m.month_val) AS datamonth,
    m.month_val AS year_month
FROM (
    SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 6 MONTH), '%Y-%m') AS month_val
    UNION SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 5 MONTH), '%Y-%m')
    UNION SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 4 MONTH), '%Y-%m')
    UNION SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 3 MONTH), '%Y-%m')
    UNION SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 2 MONTH), '%Y-%m')
    UNION SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), '%Y-%m')
    UNION SELECT DATE_FORMAT(CURDATE(), '%Y-%m')
) m
LEFT JOIN (
    SELECT 
        COUNT(id) AS datacount,
        DATE_FORMAT(created_date, '%Y-%m') AS year_month
    FROM data
    WHERE created_date >= DATE_SUB(CURDATE(), INTERVAL 7 MONTH)
    GROUP BY year_month
) d ON m.month_val = d.year_month
ORDER BY m.month_val;

输出结果示例

假设当前日期为2023-07,执行后会输出完整的近7个月统计:

datacount | datamonth | year_month
0         | 1         | 2023-01
1         | 2         | 2023-02
1         | 3         | 2023-03
0         | 4         | 2023-04
0         | 5         | 2023-05
0         | 6         | 2023-06
3         | 7         | 2023-07

内容的提问来源于stack exchange,提问作者mm1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:40:18