sql >> Base de Datos >  >> RDS >> PostgreSQL

Funciones de ventana:last_value(ORDER BY... ASC) igual que last_value(ORDER BY... DESC)

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