- Usa
COALESCE
come fornito da @Justin. -
Con
first_value()
/last_value()
di cui hai bisogno per aggiungere unORDER BY
clausola alla definizione della finestra o l'ordine è non definito . Sei stato fortunato nell'esempio, perché le righe sono in ordine subito dopo aver creato la tabella fittizia.
Una volta aggiuntoORDER BY
, la cornice della finestra predefinita termina nella riga corrente , e hai bisogno di un caso specialelast_value()
call - o ripristina l'ordinamento nella cornice della finestra come mostrato nel mio primo esempio. -
Quando riutilizzi una definizione di finestra più volte, un
WINDOW
esplicito la clausola semplifica molto la sintassi:
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);
Meglio ancora , riutilizza la stessa definizione di finestra, così Postgres può calcolare tutti i valori in una singola scansione. Affinché ciò funzioni, dobbiamo definire una cornice della finestra personalizzata :
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;
Puoi persino adattare la definizione del frame per ogni chiamata di funzione della finestra:
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;
Potrebbe essere più veloce per anelli con molte parti. Dovrai fare un test.
SQL Fiddle dimostrando tutti e tre con un test case migliorato. Prendi in considerazione i piani di query.
Ulteriori informazioni sulle definizioni dei frame delle finestre:
- Nel manuale.
- Funzione finestra PostgreSQL:partizione per confronto
- Query PostgreSQL con data massima e minima più ID associato per riga