PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Summe über Partitionen mit Fensterfunktionen

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;

Geben Sie zuerst die tatsächlichen Werte und danach NULL ein Werte in einer Gruppe mit der aggregierten Fensterfunktion count() :Es wird nicht mit NULL erhöht Werte.

Dann nehmen Sie max() aus jeder Gruppe, um zu dem zu gelangen, wonach Sie suchen. An dieser Stelle könnten Sie genauso gut min() verwenden oder sum() , da es nur einen Nicht-Null-Wert pro Gruppe gibt.

COALESCE() fängt NULL ab Werte, wenn der gesamte erste Wert in der Zeit NULL ist .

Beachten Sie, wie ich ts ausgewählt habe als Spaltenname, da ich keine Basistypnamen wie time verwende als Identifikatoren.

Testfall

So sollten Sie auch überhaupt erst einmal Beispieldaten bereitstellen!

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);