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

Teil 2:Wie man die Summe einer partitionsbasierten Abfrage erhält, ohne tatsächlich zu schwenken

Verwenden Sie die Lösung, die Sie haben (entweder eine, ich bevorzuge aus offensichtlichen Gründen die Array-Lösung), fügen Sie sie in einen CTE ein und verwenden Sie dann UNION, um die Summen zu berechnen:

with students as (
  select studentnr, 
         name, 
         gradenumber, 
         languages[1] as language_1,
         languages[2] as language_2,
         languages[3] as language_3,
         languages[4] as language_4,
         languages[5] as language_5
  FROM (       
    SELECT s.studentnumber as studentnr, 
           p.firstname AS name,
           sl.gradenumber as gradenumber,
           array_agg(DISTINCT l.text) as languages
    FROM student s
        JOIN pupil p ON p.id = s.pupilid    
        JOIN pupillanguage pl on pl.pupilid = p.id
        JOIN language l on l.id = pl.languageid
        JOIN schoollevel sl ON sl.id = p.schoollevelid
    GROUP BY s.studentnumber, p.firstname
  ) t
)
select *
from students
union all
select null as studentnr,
       null as name, 
       null as gradenumber, 
       count(language_1)::text,
       count(language_2)::text, 
       count(language_3)::text, 
       count(language_4)::text, 
       count(language_5)::text
from students;

Aggregatfunktionen wie count() ignorieren Sie NULL Werte, sodass nur Zeilen gezählt werden, in denen eine Sprache vorhanden ist.

Die Datentypen aller Spalten in den Abfragen einer UNION müssen übereinstimmen, sodass Sie in einer Spalte in der zweiten Abfrage keine ganzzahligen Werte zurückgeben können, wenn die erste Abfrage diese Spalte als Text (oder Varchar) definiert. Deshalb das Ergebnis von count() muss in text umgewandelt werden

Die Spaltenaliase in der zweiten Abfrage sind nicht wirklich notwendig, aber ich habe sie hinzugefügt, um zu zeigen, wie die Spaltenlisten übereinstimmen müssen