窗口函数中RANGE BETWEEN和ROWS BETWEEN的区别

我将通过具体例子说明 RANGE BETWEEN 和 ROWS BETWEEN 的核心区别。

一、示例数据

假设有销售表transaction_detail ,记录每天的销售额:

product

transaction_time

amount

 

华为

2018-01-01 00:00:00

5000

 

华为

2018-01-02 00:00:00

4800

 

华为

2018-01-03 00:00:00

5000

 

华为

2018-01-05 00:00:00

6500

(注意:01-04 无数据)

华为

2018-01-05 00:00:00

8000

(同一日两笔交易)

华为

2018-01-06 00:00:00

5600

 

 

二、核心区别

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)

关键点:
    • 按日期差值筛选:INTERVAL 2 DAY PRECEDING 表示当前日期的前 2 天(如 01-05 的范围是 01-03 至 01-05)。
    • 忽略日期间隙:即使 01-04 无数据,也会按实际日期计算范围。
    • 合并重复值:同一日期的多行数据(如 01-05 的两笔交易)会被全部包含。

 

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 行 + 当前行)

 

关键点:
    • 按行号偏移量筛选:2 PRECEDING 表示当前行的前 2 行(无论日期是否连续)。
    • 严格按物理行计算:即使 01-04 无数据,也会按行号选取前 2 行(如 01-05 的第一笔交易取到 01-03 和 01-05 的前一笔)。
    • 逐行处理重复值:同一日期的多行数据会被单独计算(如 01-05 的第二笔交易取到前两行和自身)。

 

 

三、应用场景对比

场景

RANGE BETWEEN 适合

ROWS BETWEEN 适合

计算近 7 天销售额

✅ 自动跳过无交易的日期(如周末)

❌ 若周末无数据,会导致行偏移错误

计算移动平均(3 行)

❌ 可能包含不连续日期的数据

✅ 严格按连续 3 行计算,不考虑日期间隙

处理重复日期

✅ 自动合并同一日的所有交易

❌ 逐行计算,可能导致重复累加

 

四、总结

特性

RANGE BETWEEN

ROWS BETWEEN

范围依据

逻辑值(如日期、数值)的差值

物理行号的偏移量

处理日期间隙

自动忽略无数据的日期

严格按行号计算,不受日期影响

处理重复值

合并同一逻辑值的所有行

逐行处理,不合并

典型场景

按时间范围统计(如近 7 天销量)

固定行数的滑动窗口(如移动平均)

 

选择哪种方式取决于你的数据特性和统计需求:若需按实际时间范围统计,用 RANGE;若需固定行数的计算,用 ROWS。

 

posted @ 2025-06-04 10:05  业余砖家  阅读(321)  评论(0)    收藏  举报