Hier is een korte vraag om het gedrag te illustreren:
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)
De uitvoer van de bovenstaande query kan hier worden bekeken (SQLFiddle hier ):
| 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 |
Weinig mensen denken aan de impliciete frames die worden toegepast op vensterfuncties die een ORDER BY
hebben clausule. In dit geval worden vensters standaard ingesteld op het frame RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
. (RANGE is niet precies hetzelfde als RIJEN, maar dat is een ander verhaal). Denk er zo over na:
- Op de rij met
v = 1
het bestelde raamkozijn omspantv IN (1)
- Op de rij met
v = 2
het bestelde raamkozijn omspantv IN (1, 2)
- Op de rij met
v = 3
het bestelde raamkozijn omspantv IN (1, 2, 3)
- Op de rij met
v = 4
het bestelde raamkozijn omspantv IN (1, 2, 3, 4)
Als je dat gedrag wilt voorkomen, heb je twee opties:
- Gebruik een expliciete
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
clausule voor besteld vensterfuncties - Gebruik geen
ORDER BY
clausule in die vensterfuncties die het mogelijk maken om ze weg te laten (alsMAX(v) OVER()
)
Meer details worden uitgelegd in dit artikel over LEAD()
, LAG()
, FIRST_VALUE()
en LAST_VALUE()