PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Parte 2:come ottenere la somma di una query basata su partizione senza effettivamente ruotare

Usa la soluzione che hai (una delle due, preferisco la soluzione array per ovvi motivi), inseriscila in un CTE, quindi usa UNION per calcolare i totali:

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;

Funzioni aggregate come count() ignora NULL valori, quindi conterà solo le righe in cui esiste una lingua.

I tipi di dati di tutte le colonne nelle query di UNION devono corrispondere, quindi non puoi restituire valori interi in una colonna nella seconda query se la prima query definisce quella colonna come testo (o varchar). Ecco perché il risultato di count() deve essere trasmesso a text

Gli alias di colonna nella seconda query non sono realmente necessari, ma li ho aggiunti per mostrare come devono corrispondere gli elenchi di colonne