Използвайте решението, което имате (което и да е, предпочитам решението с масив по очевидни причини), поставете го в CTE, след което използвайте UNION, за да изчислите сумите:
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;
Агрегирани функции като count()
игнорирайте NULL
стойности, така че ще брои само редове, където съществува език.
Типовете данни на всички колони в заявките на UNION трябва да съвпадат, така че не можете да върнете цели числа в колона във втората заявка, ако първата заявка дефинира тази колона като текст (или varchar). Ето защо резултатът от count()
трябва да се преобразува в text
Псевдонимите на колоните във втората заявка всъщност не са необходими, но ги добавих, за да покажа как списъците с колони трябва да съвпадат