SQL统计近7天、20天及YTD销售计数结果异常如何修正
问题原因
你当前用的CASE WHEN是互斥匹配逻辑:每条销售数据只会命中第一个符合条件的分支,近7天的数据不会进入近20天统计,前两个时段之外的数据才会被分到YTD分支,最终YTD返回的是年初至今排除近20天的剩余数据,不是完整的年初至今计数。
另外原代码存在两个细节问题:
- 近20天的判断条件写的是
current_date - sales_date <=28,实际统计的是近28天数据,和需求不符 - 写死
'2022-01-01'作为YTD起始日期,跨年时需要手动修改,维护成本高
调整方案
要得到正确的统计结果(YTD为完整年初至今计数,包含近7天、近20天数据),需要放弃互斥分组的写法,三个时段独立筛选统计。
如果需要保留原查询「地区+时段标签」的长表输出格式,用UNION ALL拼接三个统计段结果即可,参考代码如下:
-- 近7天销售计数 SELECT sales_region AS region, 'Past7' AS trendsales, COUNT(*) AS salescount FROM sales_table WHERE sales_date >= CURRENT_DATE - INTERVAL '7 day' AND sales_date >= DATE_TRUNC('year', CURRENT_DATE) GROUP BY sales_region UNION ALL -- 近20天销售计数 SELECT sales_region AS region, 'Past20' AS trendsales, COUNT(*) AS salescount FROM sales_table WHERE sales_date >= CURRENT_DATE - INTERVAL '20 day' AND sales_date >= DATE_TRUNC('year', CURRENT_DATE) GROUP BY sales_region UNION ALL -- 年初至今全量销售计数 SELECT sales_region AS region, 'YTD' AS trendsales, COUNT(*) AS salescount FROM sales_table WHERE sales_date >= DATE_TRUNC('year', CURRENT_DATE) GROUP BY sales_region;
说明:如果使用的数据库不支持
INTERVAL、DATE_TRUNC语法(如旧版MySQL、部分轻量嵌入式数据库),替换为对应数据库的日期计算函数即可,核心逻辑不变。
如果需要宽表输出(每个地区一行,三列分别对应三个时段的计数),可以用更简洁的条件聚合写法:
SELECT sales_region AS region, COUNT(CASE WHEN sales_date >= CURRENT_DATE - INTERVAL '7 day' THEN sales_id END) AS past7_salescount, COUNT(CASE WHEN sales_date >= CURRENT_DATE - INTERVAL '20 day' THEN sales_id END) AS past20_salescount, COUNT(*) AS ytd_salescount FROM sales_table WHERE sales_date >= DATE_TRUNC('year', CURRENT_DATE) GROUP BY sales_region;
内容的提问来源于stack exchange,提问作者batchnet
相关产品推荐
相关产品推荐

