如何在不应用透视功能的情况下为不同的字段创建列

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

所以我有一个问题要问那些胆小的人!我对这个概念有一段时间的疑问,我需要清除它...... 以下代码显示了拥有超过 1 种语言的学生

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 

结果

现在我的问题很简单,但我不确定答案是什么...我想拆分这些语言并将它们放在单独的字段中,所以它看起来像这样

想要的结果

还有1个主要问题。这是使用 Postgresql 9.3 现在不允许分组集或汇总或多维数据集。但是我尝试了这段代码,但它无法正常工作,我不确定如何处理它,也不确定如何继续处理它...

(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

表格是这样的

Language Table 
iD                   PK
shorttext            char varying
text                 char varying

PupilLanguage Table

id                   PK
languageid           FK
personid             FK
displayorder         int

一个SQL查询returns固定数量的列。如果你只需要三个额外的列,那么你可以使用动态聚合:

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;

但是,如果您想要可变数字,则需要 crosstab 或动态 SQL。我可能还建议您考虑使用数组。

如果列数固定,可以使用数组:

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

请注意,使用 group by

时通常不需要 distinct