这里有一个快速查询来说明这种行为:
select
v,
-- FIRST_VALUE() and LAST_VALUE()
first_value(v) over(order by v) f1,
first_value(v) over(order by v rows between unbounded preceding and current row) f2,
first_value(v) over(order by v rows between unbounded preceding and unbounded following) f3,
last_value (v) over(order by v) l1,
last_value (v) over(order by v rows between unbounded preceding and current row) l2,
last_value (v) over(order by v rows between unbounded preceding and unbounded following) l3,
-- For completeness' sake, let's also compare the above with MAX()
max (v) over() m1,
max (v) over(order by v) m2,
max (v) over(order by v rows between unbounded preceding and current row) m3,
max (v) over(order by v rows between unbounded preceding and unbounded following) m4
from (values(1),(2),(3),(4)) t(v)
上述查询的输出可以在这里看到(SQLFiddle here):
| V | F1 | F2 | F3 | L1 | L2 | L3 | M1 | M2 | M3 | M4 |
|---|----|----|----|----|----|----|----|----|----|----|
| 1 | 1 | 1 | 1 | 1 | 1 | 4 | 4 | 1 | 1 | 4 |
| 2 | 1 | 1 | 1 | 2 | 2 | 4 | 4 | 2 | 2 | 4 |
| 3 | 1 | 1 | 1 | 3 | 3 | 4 | 4 | 3 | 3 | 4 |
| 4 | 1 | 1 | 1 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
很少有人会想到应用于带有ORDER BY 子句的窗口函数的隐式框架。在这种情况下,窗口默认为框架RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。 (RANGE 与 ROWS 并不完全相同,但那是另一回事了)。这样想:
- 在带有
v = 1 的行上,有序窗口的框架跨越v IN (1)
- 在带有
v = 2 的行上,有序窗口的框架跨越v IN (1, 2)
- 在带有
v = 3 的行上,有序窗口的框架跨越v IN (1, 2, 3)
- 在带有
v = 4 的行上,有序窗口的框架跨越v IN (1, 2, 3, 4)
如果你想阻止这种行为,你有两个选择:
- 对有序窗口函数使用显式
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING子句
- 在允许省略它们的窗口函数中不使用
ORDER BY 子句(如MAX(v) OVER())
更多细节在this article about LEAD(), LAG(), FIRST_VALUE() and LAST_VALUE()中解释