月度时间过滤失效:按字母统计上月/当月任务数的SQL问题
按字母统计上月/当月任务量并计算月环比的SQL修正方案
原问题与错误表现
需要按字母分组统计上月、当月的任务数量,但原SQL存在逻辑错误,导致:
- 同一字母按月份重复出现,输出结果冗余
- 上月、当月列数值完全重复,无法区分对应月份的真实数据
- 日期范围计算逻辑混乱,无法准确过滤目标月份数据
原SQL脚本
SELECT column1 AS 'letter', COUNT(`tasks`.`created_at` >= str_to_date(concat(date_format(date_add(now(6), INTERVAL -1 month), '%Y-%m'), '-01'), '%Y-%m-%d') AND `tasks`.`created_at` < str_to_date(concat(date_format(`tasks`.`created_at`, '%Y-%m'), '-01'), '%Y-%m-%d')) AS `previous`, COUNT(`tasks`.`created_at` >= str_to_date(concat(date_format(`Lead Task Logs`.`created_at`, '%Y-%m'), '-01'), '%Y-%m-%d') AND `tasks`.`created_at` < str_to_date(concat(date_format(date_add(now(6), INTERVAL 1 month), '%Y-%m'), '-01'), '%Y-%m-%d')) AS `current` FROM my_table GROUP BY str_to_date(concat(date_format(`tasks`.`created_at`, '%Y-%m'), '-01'), '%Y-%m-%d') ORDER BY str_to_date(concat(date_format(`tasks`.`created_at`, '%Y-%m'), '-01'), '%Y-%m-%d') ;
当前错误输出
| 字母 | 上月 | 当月 |
|---|---|---|
| A | 4 | 4 |
| A | 3 | 3 |
| B | 8 | 8 |
| C | 4 | 4 |
| D | 12 | 12 |
| D | 3 | 3 |
| E | 2 | 2 |
| E | 2 | 2 |
期望输出
| 字母 | 上月 | 当月 |
|---|---|---|
| A | 4 | 3 |
| B | 8 | |
| C | 4 | |
| D | 12 | 3 |
| E | 2 | 2 |
修正后的SQL(含月环比计算)
SELECT column1 AS letter, -- 统计上月任务数量:日期在上月1日至当月1日之间 COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(NOW(), '%Y-%m-01'), 1, NULL)) AS previous, -- 统计当月任务数量:日期在当月1日至下月1日之间 COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(NOW(), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 MONTH), '%Y-%m-01'), 1, NULL)) AS current, -- 计算月环比增长率,处理上月为0的情况避免除以0 CASE WHEN COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(NOW(), '%Y-%m-01'), 1, NULL)) = 0 THEN NULL ELSE ROUND( (COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(NOW(), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 MONTH), '%Y-%m-01'), 1, NULL)) - COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(NOW(), '%Y-%m-01'), 1, NULL))) / COUNT(IF(`tasks`.`created_at` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(NOW(), '%Y-%m-01'), 1, NULL)) * 100, 2) END AS mom_growth_rate FROM my_table -- 提前过滤非上月/当月数据,提升查询效率 WHERE `tasks`.`created_at` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') AND `tasks`.`created_at` < DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 MONTH), '%Y-%m-01') GROUP BY column1 -- 核心修正:按字母分组,确保每个字母仅一行结果 ORDER BY column1;
关键修改说明
- 分组逻辑修正:将GROUP BY改为按
column1(字母)分组,彻底解决同一字母重复出现的问题 - 条件统计修正:用
COUNT(IF(条件,1,NULL))替代原COUNT逻辑,仅统计满足条件的行,避免无效计数 - 日期范围修正:统一用
DATE_FORMAT生成标准的上月/当月/下月起始日期,确保所有行使用一致的过滤区间 - 新增环比计算:通过CASE处理上月数量为0的异常情况,以百分比形式输出月环比增长率(保留两位小数)
- 添加WHERE过滤:提前排除非目标月份的数据,减少计算量,提升查询性能
内容的提问来源于stack exchange,提问作者juanigalvalisi
相关产品推荐
相关产品推荐

