Zde je rychlý dotaz pro ilustraci tohoto chování:
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)
Výstup výše uvedeného dotazu si můžete prohlédnout zde (SQLFiddle zde ):
| 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 |
Málokdo si myslí o implicitních rámcích, které se aplikují na funkce okna, které přebírají ORDER BY
doložka. V tomto případě jsou okna ve výchozím nastavení rámce RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
. (RANGE není úplně stejný jako ROWS, ale to je jiný příběh). Přemýšlejte o tom takto:
- Na řádku s
v = 1
rám objednaného okna se rozprostíráv IN (1)
- Na řádku s
v = 2
rám objednaného okna se rozprostíráv IN (1, 2)
- Na řádku s
v = 3
rám objednaného okna se rozprostíráv IN (1, 2, 3)
- Na řádku s
v = 4
rám objednaného okna se rozprostíráv IN (1, 2, 3, 4)
Pokud chcete tomuto chování zabránit, máte dvě možnosti:
- Použít explicitní
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
doložka pro objednáno funkce okna - Nepoužívejte
ORDER BY
klauzule v těch funkcích okna, které umožňují jejich vynechání (jakoMAX(v) OVER()
)
Další podrobnosti jsou vysvětleny v tento článek o LEAD()
, LAG()
, FIRST_VALUE()
a LAST_VALUE()