El problema con LAST_VALUE()
es que las reglas predeterminadas para las cláusulas de ventana eliminan los valores que realmente desea. Este es un problema muy sutil y es cierto en todas las bases de datos que admiten esta funcionalidad.
Esto viene de un blog de Oracle:
Mientras estamos en el tema de las cláusulas de ventana, la cláusula de ventana implícita e invariable para las funciones PRIMERA y ÚLTIMA es FILAS ENTRE LA PRECEDENTE SIN LÍMITES Y LA SIGUIENTE SIN LÍMITES, en otras palabras, todas las filas en nuestra partición. Para FIRST_VALUE y LAST_VALUE, la cláusula de ventana predeterminada pero modificable es FILAS ENTRE LA FILA ACTUAL Y PRECEDENTE SIN LÍMITES, en otras palabras, excluimos las filas posteriores a la actual. Quitar filas de la parte inferior de una lista no hace ninguna diferencia cuando buscamos la primera fila de la lista ( FIRST_VALUE), pero hace una diferencia cuando buscamos la última fila en la lista (LAST_VALUE) por lo que, por lo general, necesitará especificar FILAS ENTRE LAS PRECEDENTES SIN LÍMITES Y LAS SIGUIENTES SIN LÍMITES explícitamente cuando use LAST_VALUE o simplemente use FIRST_VALUE e invierta el orden de clasificación .
Por lo tanto, solo use FIRST_VALUE()
. Esto hace lo que quieres:
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