Voici une requête rapide pour illustrer le comportement :
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)
La sortie de la requête ci-dessus peut être vue ici (SQLFiddle ici ):
| 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 |
Peu de gens pensent aux cadres implicites appliqués aux fonctions de fenêtre qui prennent un ORDER BY clause. Dans ce cas, les fenêtres utilisent par défaut le cadre RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW . (RANGE n'est pas exactement la même chose que ROWS, mais c'est une autre histoire). Pensez-y de cette façon :
- Sur la ligne avec
v = 1le cadre de la fenêtre ordonnée s'étend surv IN (1) - Sur la ligne avec
v = 2le cadre de la fenêtre ordonnée s'étend surv IN (1, 2) - Sur la ligne avec
v = 3le cadre de la fenêtre ordonnée s'étend surv IN (1, 2, 3) - Sur la ligne avec
v = 4le cadre de la fenêtre ordonnée s'étend surv IN (1, 2, 3, 4)
Si vous souhaitez empêcher ce comportement, vous avez deux options :
- Utilisez un
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGclause pour commandé fonctions de fenêtre - N'utilisez pas de
ORDER BYclause dans ces fonctions de fenêtre qui permettent de les omettre (commeMAX(v) OVER())
Plus de détails sont expliqués dans cet article sur LEAD() , LAG() , FIRST_VALUE() et LAST_VALUE()