How to create columns for different fields without applying the pivoting function

故事扮演 提交于 2019-12-20 06:16:27

问题


So i have a question for the tough hearted! I have had an issue with this concept for awhile and I need it to be cleared... The following code shows students who have more than 1 language

SELECT DISTINCT s.studentnumber as studentnr, 
    p.firstname AS name,
    sl.gradenumber as gradenumber,
    string_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 

Result

Now my question is simple yet I'm not sure how the answer would be... I want to split up those languages and put them in seperate fields so its looks something like this

Wanted Result

There is also 1 major issue. This is using Postgresql 9.3 which doesnt now allow grouping set or rollup or cube. I tried this code however and its not working correctly, im not sure how to deal with it and im not sure how to go forward about it...

(select distinct l.text 
            from language 
            join pupillanguage pl2 on pl2.languageid = language.id 
            join pupil on p.id = pl2.personid
            limit 1) as language1

This is how the Tables looks like

Language Table 
iD                   PK
shorttext            char varying
text                 char varying

PupilLanguage Table

id                   PK
languageid           FK
personid             FK
displayorder         int

回答1:


If you have a fixed number of columns, you can use an array:

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

Note that distinct is usually not needed when you use group by




回答2:


A SQL query returns a fixed number of columns. If you want just three additional columns, then you can use dynamic aggregation:

with t as (
      SELECT s.studentnumber as studentnr, p.firstname AS name,
             sl.gradenumber as gradenumber, l.text as language,
             dense_rank() over (partition by s.studentnumber, p.firstname, sl.gradenumber order by l.text) as seqnum
      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
     )
select studentnr, name, gradenumber,
       max(case when seqnum = 1 then language end) as language_1,
       max(case when seqnum = 2 then language end) as language_2,
       max(case when seqnum = 3 then language end) as language_3
from t
group by studentnr, name, gradenumber;

However, if you want a variable number, then you need crosstab or dynamic SQL. I might also suggest that you consider arrays instead.



来源:https://stackoverflow.com/questions/50581829/how-to-create-columns-for-different-fields-without-applying-the-pivoting-functio

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