Проблемът с LAST_VALUE()
е, че правилата по подразбиране за клаузите за прозорец премахват стойностите, които наистина искате. Това е много фин проблем и е вярно във всички бази данни, които поддържат тази функционалност.
Това идва от блог на Oracle:
Докато сме по темата за клаузите за прозорец, имплицитната и неизменна клауза за прозорец за функциите FIRST и LAST е РЕД МЕЖДУ НЕОГРАНИЧЕН ПРЕДШЕСТВАЩ И НЕОГРАНИЧЕН СЛЕД, с други думи всички редове в нашия дял. За FIRST_VALUE и LAST_VALUE клаузата за прозорец по подразбиране, но променлива, е РЕДОВЕ МЕЖДУ НЕОБГРАНИЧЕН ПРЕДИШЕН И ТЕКУЩ РЕД, с други думи изключваме редове след текущия. Изпускането на редове от дъното на списъка не прави разлика, когато търсим първия ред в списъка ( FIRST_VALUE), но прави разлика, когато търсим последния ред в списъка (LAST_VALUE) така че обикновено ще трябва или да посочите ROWS BETWEENUNBOUNDED PRECEDING И UNBOUNDED FOLLOWING изрично, когато използватеLAST_VALUE, или просто да използвате FIRST_VALUE и да обърнете реда на сортиране .
Следователно, просто използвайте FIRST_VALUE()
. Това прави това, което искате:
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