转置sql结果,使一列进入多列

Yul*_*ule 5 sql postgresql crosstab

我正试图从一个表格中获取特定格式的调查数据.但是我的所有尝试似乎都是因为DB上的连接太多/太重而无法提交数据库.

我的数据如下:

id, user, question_id, answer_id, 
1,   1,   1,           1
3,   1,   3,           15
4,   2,   1,           2
5,   2,   2,           12
6,   2,   3,           20
Run Code Online (Sandbox Code Playgroud)

大约有250,000行,每个用户大约有30行.我希望结果看起来像:

user0, q1, q2,   q3 
1,     1,  NULL, 15
2,     2,  12,   20 
Run Code Online (Sandbox Code Playgroud)

这样每个用户在结果中都有一行,每个用户每个答案都有一个单独的列.

我正在使用Postgres,但任何SQL语言的答案都会受到赞赏,因为我可以翻译成Postgres.

编辑:我还需要能够处理不回答问题的用户,即上面的示例q2用户1.

Erw*_*ter 6

请考虑以下演示:

CREATE TEMP TABLE qa (id int, usr int, question_id int, answer_id int);
INSERT INTO qa VALUES
 (1,1,1,1)
,(2,1,2,9)
,(3,1,3,15)
,(4,2,1,2)
,(5,2,2,12)
,(6,2,3,20);

SELECT *
FROM   crosstab('
    SELECT usr::text
          ,question_id
          ,answer_id
    FROM qa
    ORDER BY 1,2')
 AS ct (
     usr text
    ,q1 int
    ,q2 int
    ,q3 int);
Run Code Online (Sandbox Code Playgroud)

结果:

 usr | q1 | q2 | q3
-----+----+----+----
 1   |  1 |  9 | 15
 2   |  2 | 12 | 20
(2 rows)
Run Code Online (Sandbox Code Playgroud)

user是一个保留字.不要将它用作列名!我把它重命名为usr.

您需要安装提供该功能的附加模块tablefunccrosstab().请注意,此操作严格按照数据库进行.在PostgreSQL 9.1中,您可以简单地:

CREATE EXTENSION tablefunc;
Run Code Online (Sandbox Code Playgroud)

对于旧版本,您将执行contrib目录中提供的shell脚本.在Debian中,对于PostgreSQL 8.4,它将是:

psql mydb -f /usr/share/postgresql/8.4/contrib/tablefunc.sql
Run Code Online (Sandbox Code Playgroud)