如何在不应用透视功能的情况下为不同的字段创建列
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
所以我有一个问题要问那些胆小的人!我对这个概念有一段时间的疑问,我需要清除它...... 以下代码显示了拥有超过 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