PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Fensterfunktionen:last_value(ORDER BY ... ASC) wie last_value(ORDER BY ... DESC)

Das Problem mit LAST_VALUE() ist, dass die Standardregeln für Windowing-Klauseln die Werte entfernen, die Sie wirklich wollen. Dies ist ein sehr subtiles Problem und trifft auf alle Datenbanken zu, die diese Funktionalität unterstützen.

Dies stammt aus einem Oracle-Blog:

Wo wir gerade beim Thema Windowing-Klauseln sind, die implizite und unveränderliche Window-Klausel für die FIRST- und LAST-Funktionen ist ROWSBETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, mit anderen Worten alle Zeilen in unserer Partition. Für FIRST_VALUE und LAST_VALUE ist die standardmäßige, aber änderbare Windowing-Klausel ROWS BETWEEN UNBOUNDED PRECEDINGAND CURRENT ROW, mit anderen Worten, wir schließen Zeilen nach der aktuellen Zeile aus. Das Löschen von Zeilen am Ende einer Liste macht keinen Unterschied, wenn wir nach der ersten Zeile in der Liste suchen ( FIRST_VALUE), aber es macht einen Unterschied, wenn wir nach der letzten Zeile in der Liste suchen (LAST_VALUE) also müssen Sie normalerweise entweder ROWS BETWEENUNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING explizit angeben, wenn Sie LAST_VALUE verwenden, oder einfach FIRST_VALUE verwenden und die Sortierreihenfolge umkehren .

Verwenden Sie daher einfach FIRST_VALUE() . Das macht was du willst:

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