Part 2: how to get the Sum of a partition based query without actually pivoting

若如初见. 提交于 2019-12-02 06:19:00

Use the the solution you have (either one, I prefer the array solution for obvious reasons), put it into a CTE, then use UNION to calculate the totals:

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;

Aggregate functions like count() ignore NULL values, so it will only count rows where a language exists.

The data types of all columns in the queries of a UNION have to match, so you can't return integer values in a column in the second query if the first query defines that column as text (or varchar). That's why the result of the count() needs to be cast to text

The column aliases in the second query aren't really necessary, but I have added them to show how the column lists have to match

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!