- Utilisez
COALESCE
comme @Justin fourni. -
Avec
first_value()
/last_value()
vous avez besoin pour ajouter unORDER BY
clause à la définition de la fenêtre ou l'ordre est indéfini . Vous avez juste eu de la chance dans l'exemple, car les lignes sont dans l'ordre juste après la création de la table factice.
Une fois que vous avez ajoutéORDER BY
, le cadre de fenêtre par défaut se termine à la ligne courante , et vous devez cas particulier lelast_value()
call - ou inverser l'ordre de tri dans le cadre de la fenêtre comme démontré dans mon premier exemple. -
Lors de la réutilisation d'une définition de fenêtre plusieurs fois, un
WINDOW
explicite clause simplifie beaucoup la syntaxe :
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);
Mieux encore , réutilisez la même définition de fenêtre, afin que Postgres puisse calculer toutes les valeurs en une seule analyse. Pour que cela fonctionne, nous devons définir un cadre de fenêtre personnalisé :
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;
Vous pouvez même adapter la définition du cadre pour chaque appel de fonction de fenêtre :
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;
Peut-être plus rapide pour les anneaux avec de nombreuses pièces. Vous devrez tester.
Violon SQL démontrant les trois avec un cas de test amélioré. Envisagez des plans de requête.
En savoir plus sur les définitions de cadre de fenêtre :
- Dans le manuel.
- Fonction de fenêtre PostgreSQL :partitionner par comparaison
- Requête PostgreSQL avec date max et min plus identifiant associé par ligne