- Użyj
COALESCE
jak podał @Justin. -
Z
first_value()
/last_value()
potrzebujesz aby dodaćORDER BY
klauzula do definicji okna lub kolejność jest nieokreślona . Po prostu miałeś szczęście w tym przykładzie, ponieważ wiersze są w porządku zaraz po utworzeniu fikcyjnej tabeli.
Po dodaniuORDER BY
, domyślna ramka okna kończy się w bieżącym wierszu , i musisz użyć specjalnej wielkości literlast_value()
zadzwoń - lub przywróć porządek sortowania w ramce okna, jak pokazano w moim pierwszym przykładzie. -
Podczas wielokrotnego używania definicji okna, jawne
WINDOW
klauzula znacznie upraszcza składnię:
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);
Jeszcze lepiej , ponownie użyj tej samej definicji okna, aby Postgres mógł obliczyć wszystkie wartości w jednym skanie. Aby to zadziałało, musimy zdefiniować niestandardową ramę okna :
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;
Możesz nawet dostosować definicję ramki dla każdego wywołania funkcji okna:
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;
Może być szybszy w przypadku pierścionków z wieloma częściami. Będziesz musiał przetestować.
Skrzypce SQL demonstrowanie wszystkich trzech z ulepszonym przypadkiem testowym. Rozważ plany zapytań.
Więcej o definicjach ram okiennych:
- W instrukcji.
- Funkcja okna PostgreSQL:partycja przez porównanie
- Zapytanie PostgreSQL z maksymalną i minimalną datą oraz powiązanym identyfikatorem na wiersz