- Použijte
COALESCE
jako @Justin poskytl. -
Pomocí
first_value()
/last_value()
potřebujete přidatORDER BY
klauzule k definici okna nebo objednávka je nedefinovaná . Právě jste měli štěstí v příkladu, protože řádky jsou v pořádku hned po vytvoření fiktivní tabulky.
Jakmile přidáteORDER BY
, výchozí rám okna končí na aktuálním řádku a potřebujete speciální případlast_value()
call - nebo vrátit pořadí řazení v rámu okna, jak je ukázáno v mém prvním příkladu. -
Při opakovaném použití definice okna vícekrát, explicitní
WINDOW
klauzule hodně zjednodušuje syntaxi:
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);
Ještě lépe znovu použít stejnou definici okna, takže Postgres může vypočítat všechny hodnoty v jediném skenování. Aby to fungovalo, musíme definovat vlastní rám 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;
Můžete dokonce přizpůsobit definici rámce pro každé volání funkce 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;
Může být rychlejší u prstenů s mnoha částmi. Budete muset otestovat.
SQL Fiddle předvedení všech tří pomocí vylepšeného testovacího případu. Zvažte plány dotazů.
Více o definicích okenních rámů:
- V příručce.
- Funkce okna PostgreSQL:porovnání rozdělení
- Dotaz PostgreSQL s maximálním a minimálním datem a přidruženým ID na řádek