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 = 1het bestelde raamkozijn omspantv IN (1) - Op de rij met
v = 2het bestelde raamkozijn omspantv IN (1, 2) - Op de rij met
v = 3het bestelde raamkozijn omspantv IN (1, 2, 3) - Op de rij met
v = 4het 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 FOLLOWINGclausule voor besteld vensterfuncties - Gebruik geen
ORDER BYclausule 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()