Postgres Crosstab 将值分配给错误的列

Mik*_*ike 5 postgresql pivot crosstab

我有一个名为 antest 的示例表,如下所示,用于测试交叉表函数。

create table antest(student text, subject text, result numeric);
insert into antest(student, subject, result) values
('peter','music',2.0), 
('peter','language',2.0),
('gabriel','history',8.0),
('john','history',9.0),
('john','maths',4.0),
('john','music',7.0);

student|subject|result
-------+-------+------
peter  |music  |2.0
peter  |lanuage|2.0
gabriel|history|8.0
john   |history|9.0
john   |maths  |4.0
john   |music  |7.0
Run Code Online (Sandbox Code Playgroud)

想要的结果:

student|music|language|history|maths
-------+-----+--------+-------+-----
peter  |2.0  |2.0     |       |
gabriel|     |        |8.0    |
john   |7.0  |        |9.0    |4.0
Run Code Online (Sandbox Code Playgroud)

我已经为此执行了以下查询:

select * 
from public.crosstab (
    'select student, subject, result from antest',
    'select distinct subject from antest'
) as final_result(student text, music numeric, maths numeric, history numeric, language numeric);
Run Code Online (Sandbox Code Playgroud)

我得到了以下结果:

student|music|maths|history|language
-------+-----+-----+-------+--------
peter  |2.0  |     |       |2.0
gabriel|     |8.0  |       |
john   |7.0  |9.0  |4.0    |
Run Code Online (Sandbox Code Playgroud)

请让我知道我正在做的错误。

我必须对任何其他 30gb 大的数据库重复这个查询,大约有 75 个属性。有没有可能让它自动化?

kli*_*lin 5

您必须注意类别查询和列定义中的类别顺序完全相同。因为您想要任意选择的(非字母顺序)顺序,所以您应该values在类别查询中使用。

select * 
from crosstab (
    $q$ select student, subject, result from antest $q$,
    $q$ values ('music'), ('language'), ('history'), ('maths') $q$
) as final_result(student text, music numeric, language numeric, history numeric, maths numeric);


 student | music | language | history | maths 
---------+-------+----------+---------+-------
 peter   |   2.0 |      2.0 |         |      
 gabriel |       |          |     8.0 |      
 john    |   7.0 |          |     9.0 |   4.0
(3 rows)
Run Code Online (Sandbox Code Playgroud)

当然,您可以order by在查询中使用,但是您必须更改列定义中的顺序:

select * 
from crosstab (
    $q$ select student, subject, result from antest $q$,
    $q$ select distinct subject from antest order by 1 $q$
) as final_result(student text, history numeric, language numeric, math numeric, music numeric);

 student | history | language | math | music 
---------+---------+----------+------+-------
 peter   |         |      2.0 |      |   2.0
 gabriel |     8.0 |          |      |      
 john    |     9.0 |          |  4.0 |   7.0
(3 rows)    
Run Code Online (Sandbox Code Playgroud)