Problemet med LAST_VALUE()
är att standardreglerna för fönsterklausuler tar bort de värden du verkligen vill ha. Detta är ett mycket subtilt problem och är sant i alla databaser som stöder denna funktionalitet.
Detta kommer från en Oracle-blogg:
Medan vi är inne på ämnet fönstersatssatser, är den implicita och oföränderliga fönstersatsen för FIRST och LAST-funktionerna RADERMELLAN OBEGRÄNSAD FÖREGÅENDE OCH OBEGRÄNSAD FÖLJANDE, med andra ord alla rader i vår partition. För FIRST_VALUE och LAST_VALUE är den förinställda men föränderliga fönsterklausulen RADER MELLAN OBEGRÄNSAD FÖREGÅENDE OCH CURRENT ROW, med andra ord exkluderar vi rader efter den nuvarande. Att ta bort rader från botten av en lista gör ingen skillnad när vi letar efter den första raden i listan ( FIRST_VALUE) men det gör skillnad när vi letar efter den sista raden i listan (LAST_VALUE) så du behöver vanligtvis antingen specificera RADER MELLAN UNBOUNDED PRECEDING OCH UNBOUNDED FOLLOWING explicit när du använder LAST_VALUE eller bara använda FIRST_VALUE och vända sorteringsordningen .
Använd därför bara FIRST_VALUE()
. Detta gör vad du vill:
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