SQL如何实现各日期对应过去7天金额滚动平均值计算
原SQL问题分析
你写的SQL存在3个核心问题:
- 语法不合法:外层SELECT嵌套子查询的结构错误,缺少必要的括号和关联逻辑;开窗函数的
order by NULL会导致数据排序随机,无法保证按日期顺序取数 - 逻辑不符合需求:
lag()函数仅能获取上一行的数值,无法覆盖往前6天的所有数据,完全不满足滚动7天求平均的计算要求 - 日期处理不严谨:直接对数值格式的日期做减7计算,跨月时会得到非法日期(比如20210901减7得到20210894),导致筛选范围错误
正确实现方案
你要的滚动7天平均值直接用开窗函数的滑动窗口语法就能实现,不需要嵌套lag()函数,逻辑更简洁也更可控:
SELECT Date, Amount, AVG(Amount) OVER ( ORDER BY Date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ) AS avg FROM ( -- 先按日期汇总单日总金额,避免同一天存在多条数据导致计算错误 SELECT Date, SUM(Amount) AS Amount FROM 你的表名 GROUP BY Date ) t ORDER BY Date;
逻辑说明:
- 内层子查询先按日期分组,汇总得到每天的总金额,处理单日有多条消费记录的场景
- 外层开窗函数
ORDER BY Date保证按日期正序排序,ROWS BETWEEN 6 PRECEDING AND CURRENT ROW代表取当前行+往前6行共7行的金额求平均值,正好匹配你要的「当日+此前6天共7天滚动平均」的需求 - 如果你的日期存在断档,需要严格按自然日范围取数(不管对应日期有没有数据),可以把
ROWS改成RANGE,同时把Date字段转换为合法的日期类型计算即可,不同数据库的日期转换函数略有差异,根据实际使用的数据库调整即可
效果验证:
代入你提供的示例数据,上面的SQL输出结果和你期望的完全一致:
| Date | Amount | avg |
|---|---|---|
| 20210901 | 100 | 100 |
| 20210902 | 500 | 300 |
| 20210903 | 600 | 400 |
内容的提问来源于stack exchange,提问作者Himanshu
相关产品推荐
相关产品推荐

