Problemet med LAST_VALUE()
er, at standardreglerne for vinduesklausuler fjerner de værdier, du virkelig ønsker. Dette er et meget subtilt problem og gælder i alle databaser, der understøtter denne funktionalitet.
Dette kommer fra en Oracle-blog:
Mens vi er på emnet for vinduesklausuler, er den implicitte og uforanderlige vinduesklausul for FIRST og LAST funktioner RÆKKERMELLEM UBEGRÆNSET FØLGENDE OG UBEGRÆNSET FØLGENDE, med andre ord alle rækker i vores partition. For FIRST_VALUE og LAST_VALUE er standard-men foranderlige vinduesklausul RÆKKER MELLEM UBEGRÆNSET FORREGENDE OG AKTUELLE RÆKKE, med andre ord ekskluderer vi rækker efter den nuværende. At slippe rækker fra bunden af en liste gør ingen forskel, når vi leder efter den første række på listen ( FIRST_VALUE), men det gør en forskel, når vi leder efter den sidste række i listen(LAST_VALUE) så du skal normalt enten angive RÆKKER MELLEM UNBOUNDED PRECEDING AND UNBOUNDED FOLGENDE eksplicit, når du bruger LAST_VALUE eller bare bruge FIRST_VALUE og vende sorteringsrækkefølgen .
Brug derfor bare FIRST_VALUE()
. Dette gør, hvad du vil:
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