PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment utiliser une structure de données en anneau dans les fonctions de fenêtre

  • Utilisez COALESCE comme @Justin fourni.
  • Avec first_value() / last_value() vous avez besoin pour ajouter un ORDER 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 le last_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