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 = 1
le cadre de la fenêtre ordonnée s'étend surv IN (1)
- Sur la ligne avec
v = 2
le cadre de la fenêtre ordonnée s'étend surv IN (1, 2)
- Sur la ligne avec
v = 3
le cadre de la fenêtre ordonnée s'étend surv IN (1, 2, 3)
- Sur la ligne avec
v = 4
le 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 FOLLOWING
clause pour commandé fonctions de fenêtre - N'utilisez pas de
ORDER BY
clause 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()