因为我没有最新版本的Postgresql(我有Postgresql 9.3),所以我不可能想出一个类似于计算特定字段总值的pivot函数的函数。
您可以单击下面的链接以使用我创建的问题作为参考,它们在代码中类似但在要求方面有所不同,但是有第二个查询使用数组并且还产生完全相同的结果。
How to create columns for different fields without applying the pivoting function
我目前得到以下结果
我想要这些结果
下面我有一个查询,它返回了我在3个不同栏目中讲的语言......我的问题是我无法想出一个可以让我得到的总和的解决方案很多学生说一种语言1,说多少语言2,说多少语言3
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;
我问这个问题,因为如果没有办法做到这一点,那么如果不可能,我就不需要进一步研究它。
分区和密集的整个概念对我来说相对较新,我不确定它们产生进一步结果的程度和能力。
答案 0 :(得分:1)
使用您拥有的解决方案(其中一个,我更喜欢阵列解决方案,原因很明显),将其放入CTE,然后使用UNION计算总数:
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;
聚合函数,例如count()
忽略NULL
值,因此它只计算语言所在的行。
UNION查询中所有列的数据类型必须匹配,因此如果第一个查询将该列定义为text(或varchar),则不能在第二个查询的列中返回整数值。这就是count()
的结果需要转换为text
第二个查询中的列别名不是必需的,但我添加了它们以显示列列表必须匹配