在电商、零售等业务场景中,统计过去7天的滑动销售总额是高频需求,通过SQL的窗口函数配合ROWS 6 PRECEDING语法,可以快速实现这个统计目标,避免复杂的自连接操作。

核心语法逻辑说明
ROWS 6 PRECEDING是SQL窗口函数中用来定义行范围的关键字,它的作用是限定当前行往前数的6行数据,加上当前行本身刚好是7行数据,对应过去7天的统计范围。搭配SUM聚合函数,就可以直接计算出这7行对应字段的总和,也就是过去7天的滑动销售总额。
需要注意的是,使用这个语法的前提是数据已经按照日期升序排列,保证每一行对应的日期是连续的,否则统计出来的结果会不符合预期。
示例表结构准备
我们先假设有一张销售记录表sales_daily,表结构如下:
| 字段名 | 字段类型 | 字段说明 |
|---|---|---|
| sale_date | DATE | 销售日期 |
| product_id | INT | 商品ID |
| daily_sales | DECIMAL(10,2) | 当日销售额 |
完整实现代码
以下是计算全量数据过去7天滑动销售总额的SQL代码,以MySQL 8.0+、PostgreSQL等支持窗口函数的数据库为例:
-- 计算过去7天的滑动销售总额
SELECT
sale_date,
product_id,
daily_sales,
-- 使用SUM配合ROWS 6 PRECEDING计算滑动总和
SUM(daily_sales) OVER (
PARTITION BY product_id -- 按商品分组,分别计算每个商品的滑动总额
ORDER BY sale_date ASC -- 按日期升序排列,保证窗口范围正确
ROWS 6 PRECEDING -- 当前行+往前6行,共7行数据
) AS last_7_days_sales_total
FROM sales_daily
ORDER BY product_id, sale_date ASC;
代码逻辑解析
上述代码的核心逻辑分为几个部分:
PARTITION BY product_id:将数据按商品ID分组,保证每个商品的滑动总额是独立计算的,不会和其他商品的数据混淆。ORDER BY sale_date ASC:对每个分组内的数据按日期升序排序,这是ROWS 6 PRECEDING生效的基础,只有排序后往前数6行才是对应过去6天的数据。ROWS 6 PRECEDING:定义窗口范围为当前行以及当前行之前的6行,总共7行数据,刚好对应过去7天的统计范围。- 外层的
ORDER BY product_id, sale_date ASC:保证最终查询结果的展示顺序清晰,方便查看每个商品按日期排列的滑动总额。
特殊场景处理
如果数据中存在日期不连续的情况,比如某一天没有销售记录,那么ROWS 6 PRECEDING统计的会是往前6条记录的总和,而不是严格意义上的过去7天。这时候需要先做日期补全,保证每天都有一条记录,即使当天销售额为0,再进行滑动计算。
补全日期的参考代码如下:
-- 先补全日期,再计算滑动总额
WITH date_range AS (
-- 生成连续的日期范围,覆盖销售表的所有日期
SELECT
MIN(sale_date) AS start_date,
MAX(sale_date) AS end_date
FROM sales_daily
),
all_dates AS (
-- 递归生成所有连续日期
SELECT start_date AS sale_date
FROM date_range
UNION ALL
SELECT DATE_ADD(sale_date, INTERVAL 1 DAY)
FROM all_dates
WHERE sale_date < (SELECT end_date FROM date_range)
),
full_sales AS (
-- 补全销售数据,没有记录的日期销售额设为0
SELECT
ad.sale_date,
sd.product_id,
COALESCE(sd.daily_sales, 0) AS daily_sales
FROM all_dates ad
CROSS JOIN (SELECT DISTINCT product_id FROM sales_daily) p
LEFT JOIN sales_daily sd
ON ad.sale_date = sd.sale_date
AND p.product_id = sd.product_id
)
-- 补全后计算滑动总额
SELECT
sale_date,
product_id,
daily_sales,
SUM(daily_sales) OVER (
PARTITION BY product_id
ORDER BY sale_date ASC
ROWS 6 PRECEDING
) AS last_7_days_sales_total
FROM full_sales
ORDER BY product_id, sale_date ASC;
注意事项
不同数据库对窗口函数的支持略有差异,ROWS 6 PRECEDING语法在MySQL 8.0+、PostgreSQL、SQL Server 2012+、Oracle 10g+等版本都支持,如果是更老的数据库版本,可能无法使用这个语法,需要改用自连接的方式实现。
另外如果数据量较大,建议在sale_date和product_id字段上建立联合索引,提升窗口函数排序和分组的执行效率。
SQLROWS_6_PRECEDING滑动窗口函数销售总额计算过去7天统计修改时间:2026-07-17 11:06:29