- Verwenden Sie
COALESCE
wie von @Justin bereitgestellt. -
Mit
first_value()
/last_value()
Sie brauchen um einORDER BY
hinzuzufügen -Klausel zur Fensterdefinition oder die Reihenfolge ist undefiniert . In diesem Beispiel haben Sie einfach Glück gehabt, weil die Zeilen direkt nach dem Erstellen der Dummy-Tabelle in der richtigen Reihenfolge sind.
Sobald SieORDER BY
hinzufügen , endet der Standardfensterrahmen an der aktuellen Zeile , und Sie müssen denlast_value()
mit einem Sonderfall versehen aufrufen - oder die Sortierreihenfolge im Fensterrahmen umkehren, wie in meinem ersten Beispiel gezeigt. -
Bei mehrfacher Wiederverwendung einer Fensterdefinition wird explizit ein
WINDOW
-Klausel vereinfacht die Syntax erheblich:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,first_value(part) OVER (PARTITION BY ring ORDER BY part DESC))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part);
Noch besser , dieselbe Fensterdefinition wiederverwenden, sodass Postgres alle Werte in einem einzigen Scan berechnen kann. Damit dies funktioniert, müssen wir einen benutzerdefinierten Fensterrahmen definieren :
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER w)
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring
ORDER BY part
RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING)
ORDER BY 1,2;
Sie können sogar die Rahmendefinition für jeden Fensterfunktionsaufruf anpassen:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER (w RANGE BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part)
ORDER BY 1,2;
Kann bei Ringen mit vielen Teilen schneller sein. Sie müssen testen.
SQL-Geige Demonstration aller drei mit einem verbesserten Testfall. Ziehen Sie Abfragepläne in Betracht.
Mehr über Fensterrahmendefinitionen:
- Im Handbuch.
- PostgreSQL-Fensterfunktion:Partition durch Vergleich
- PostgreSQL-Abfrage mit maximalem und minimalem Datum plus zugehöriger ID pro Zeile