Il problema con LAST_VALUE()
è che le regole predefinite per le clausole di windowing rimuovono i valori che desideri davvero. Questo è un problema molto sottile ed è vero in tutti i database che supportano questa funzionalità.
Questo viene da un blog Oracle:
Mentre siamo in tema di clausole di windowing, la clausola di finestra implicita e immutabile per le funzioni FIRST e LAST è ROWSBETWEEN UNBOUNDED PRECEDING E UNBOUNDED FOLLOWING, in altre parole tutte le righe nella nostra partizione. Per FIRST_VALUE e LAST_VALUE la clausola di windowing predefinita ma modificabile è ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, in altre parole escludiamo le righe successive a quella corrente. Eliminare le righe dal fondo di un elenco non fa differenza quando cerchiamo la prima riga nell'elenco ( FIRST_VALUE) ma fa la differenza quando cerchiamo l'ultima riga nell'elenco (LAST_VALUE) quindi di solito sarà necessario specificare ROWS BETWEEUNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING esplicitamente quando si utilizzaLAST_VALUE o semplicemente utilizzare FIRST_VALUE e invertire l'ordinamento .
Quindi, usa semplicemente FIRST_VALUE()
. Questo fa quello che vuoi:
with test (id, session_ID, value) as (
(VALUES (0, 2, 100),
(1, 2, 120),
(2, 2, 140),
(3, 1, 900),
(4, 1, 800),
(5, 1, 500)
)
)
select id,
first_value(value) over (partition by session_ID order by id) as first_value_window,
first_value(value) over (partition by session_ID order by id desc) as first_value_window_desc
from test
order by id