Sử dụng giải pháp bạn có (một trong hai giải pháp đó, tôi thích giải pháp mảng hơn vì những lý do rõ ràng), đặt nó vào CTE, sau đó sử dụng UNION để tính tổng:
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;
Các hàm tổng hợp như count()
bỏ qua NULL
giá trị, vì vậy nó sẽ chỉ đếm các hàng có ngôn ngữ tồn tại.
Kiểu dữ liệu của tất cả các cột trong truy vấn của UNION phải khớp, vì vậy bạn không thể trả về giá trị số nguyên trong một cột trong truy vấn thứ hai nếu truy vấn đầu tiên xác định cột đó là văn bản (hoặc varchar). Đó là lý do tại sao kết quả của count()
cần được truyền sang text
Bí danh cột trong truy vấn thứ hai không thực sự cần thiết, nhưng tôi đã thêm chúng để cho biết danh sách cột phải khớp như thế nào