窗口函数中RANGE BETWEEN和ROWS BETWEEN的区别
一、示例数据
二、核心区别
1. RANGE BETWEEN:按逻辑值范围筛选
SQL语句:
SELECT product, transaction_time, amount, SUM(amount) OVER ( PARTITION BY product ORDER BY transaction_time RANGE BETWEEN INTERVAL 2 DAY PRECEDING AND CURRENT ROW ) AS range_sum FROM transaction_detail;
执行结果:
|
product |
transaction_time |
amount |
range_sum |
|
|
华为 |
2018-01-01 00:00:00 |
5000 |
5000 |
(仅当天) |
|
华为 |
2018-01-02 00:00:00 |
4800 |
9800 |
(01-01 至 01-02) |
|
华为 |
2018-01-03 00:00:00 |
5000 |
14800 |
(01-01 至 01-03) |
|
华为 |
2018-01-05 00:00:00 |
6500 |
19500 |
(01-03 至 01-05,自动跳过 01-04) |
|
华为 |
2018-01-05 00:00:00 |
8000 |
19500 |
(与上一行范围相同) |
|
华为 |
2018-01-06 00:00:00 |
5600 |
20100 |
(01-04 至 01-06,自动跳过 01-04) |
2. ROWS BETWEEN:按物理行号筛选
SQL语句:
SELECT product, transaction_time, amount, SUM(amount) OVER ( PARTITION BY product ORDER BY transaction_time ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS rows_sum FROM transaction_detail ;
执行结果:
|
product |
transaction_time |
amount |
rows_sum |
|
|
华为 |
2018-01-01 00:00:00 |
5000 |
5000 |
(仅当前行) |
|
华为 |
2018-01-02 00:00:00 |
4800 |
9800 |
(前 1 行 + 当前行) |
|
华为 |
2018-01-03 00:00:00 |
5000 |
14800 |
(前 2 行 + 当前行) |
|
华为 |
2018-01-05 00:00:00 |
6500 |
16300 |
(前 2 行 + 当前行) |
|
华为 |
2018-01-05 00:00:00 |
8000 |
19500 |
(前 2 行 + 当前行) |
|
华为 |
2018-01-06 00:00:00 |
5600 |
20100 |
(前 2 行 + 当前行) |
三、应用场景对比
|
场景 |
RANGE BETWEEN 适合 |
ROWS BETWEEN 适合 |
|
计算近 7 天销售额 |
✅ 自动跳过无交易的日期(如周末) |
❌ 若周末无数据,会导致行偏移错误 |
|
计算移动平均(3 行) |
❌ 可能包含不连续日期的数据 |
✅ 严格按连续 3 行计算,不考虑日期间隙 |
|
处理重复日期 |
✅ 自动合并同一日的所有交易 |
❌ 逐行计算,可能导致重复累加 |
四、总结
|
特性 |
RANGE BETWEEN |
ROWS BETWEEN |
|
范围依据 |
逻辑值(如日期、数值)的差值 |
物理行号的偏移量 |
|
处理日期间隙 |
自动忽略无数据的日期 |
严格按行号计算,不受日期影响 |
|
处理重复值 |
合并同一逻辑值的所有行 |
逐行处理,不合并 |
|
典型场景 |
按时间范围统计(如近 7 天销量) |
固定行数的滑动窗口(如移动平均) |
选择哪种方式取决于你的数据特性和统计需求:若需按实际时间范围统计,用 RANGE;若需固定行数的计算,用 ROWS。
本文来自博客园,作者:业余砖家,转载请注明原文链接:https://www.cnblogs.com/yeyuzhuanjia/p/18909576

浙公网安备 33010602011771号