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

Somme sur les partitions avec les fonctions de fenêtre

SELECT ts, a, b, c
       , COALESCE(max(a) OVER (PARTITION BY grp_a), 0)
       + COALESCE(max(b) OVER (PARTITION BY grp_b), 0)
       + COALESCE(max(c) OVER (PARTITION BY grp_c), 0) AS special_sum
FROM  (
   SELECT *
         ,count(a) OVER w AS grp_a
         ,count(b) OVER w AS grp_b
         ,count(c) OVER w AS grp_c
   FROM   t
   WINDOW w AS (ORDER BY ts)
   ) sub
ORDER  BY ts;

Tout d'abord, mettez les valeurs réelles et suivant NULL valeurs dans un groupe avec la fonction de fenêtre d'agrégation count() :il ne s'incrémente pas de NULL valeurs.

Ensuite, prenez max() de chaque groupe, en arrivant à ce que vous recherchez. À ce stade, vous pouvez tout aussi bien utiliser min() ou sum() , puisqu'il n'y a qu'une seule valeur non nulle par groupe.

COALESCE() attrape NULL valeurs si la première valeur globale dans le temps est NULL .

Notez comment j'ai choisi ts comme nom de colonne, car je n'utilise pas de noms de type de base comme time comme identifiants.

Cas de test

C'est également ainsi que vous devriez tous fournir des exemples de données en premier lieu !

CREATE TEMP TABLE t (ts int, a int, b int, c int);

INSERT INTO t VALUES
  (1, 11,   21,   NULL)
 ,(2, 12,   22,   NULL)
 ,(3, 13,   NULL, NULL)
 ,(4, NULL, 23,   32);