sql >> Base de Datos >  >> RDS >> PostgreSQL

Parte 2:cómo obtener la suma de una consulta basada en partición sin girar realmente

Use la solución que tiene (cualquiera de las dos, prefiero la solución de matriz por razones obvias), póngala en un CTE, luego use UNION para calcular los totales:

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;

Funciones agregadas como count() ignorar NULL valores, por lo que solo contará las filas donde exista un idioma.

Los tipos de datos de todas las columnas en las consultas de UNION deben coincidir, por lo que no puede devolver valores enteros en una columna en la segunda consulta si la primera consulta define esa columna como texto (o varchar). Es por eso que el resultado de count() debe convertirse en text

Los alias de columna en la segunda consulta no son realmente necesarios, pero los he agregado para mostrar cómo deben coincidir las listas de columnas