我很难理解如何从我正在使用的数据库中正确转置此表。该表是由几年前设计数据库的人创建的,但我设法使用 检索该表的创建语句pg_dump
。
下面是带有示例条目的表:
CREATE TABLE response (
session_id integer NOT NULL,
seconds integer NOT NULL,
question_id integer NOT NULL,
response character varying(500),
file bytea
);
INSERT INTO response(session_id, seconds, question_id, response, file)
VALUES (758,1459505869,31,'0',''), (758,1459505869,32,'0',''),
(758,1459505869,33,'0',''), (758,1459505869,34,'0',''),
(758,1459505869,35,'1',''), (758,1459505869,36,'0',''),
(758,1459505869,37,'0',''), (758,1459505869,38,'0',''),
(758,1459506973,38,'0',''), (758,1459506973,37,'0',''),
(758,1459506973,36,'0',''),(758,1459506973,35,'1',''),
(758,1459506973,34,'0',''),(758,1459506973,33,'0',''),
(758,1459506973,32,'0',''),(758,1459506973,31,'0',''),
(758,1459508676,31,'0',''),(758,1459508676,32,'0',''),
(758,1459508676,33,'0',''),(758,1459508676,34,'0',''),
(758,1459508676,35,'1',''),(758,1459508676,36,'0',''),
(758,1459508676,37,'0', ''), (758,1459508676,38,'0', '');
SELECT * FROM response LIMIT 5;
session_id seconds question_id response file
758 1459505869 31 0 [null]
758 1459505869 32 0 [null]
758 1459505869 33 0 [null]
758 1459505869 34 0 [null]
758 1459505869 35 1 [null]
Run Code Online (Sandbox Code Playgroud)
该列中的问题 IDquestion_id
代表以下内容:
30 -- not_foot_count
31 -- not_moving
32 -- foot
33 -- bicycle
34 -- motorcycle
35 -- car
36 -- bus
37 -- metro
38 -- other
39 -- train
Run Code Online (Sandbox Code Playgroud)
响应可以是文本(错误的用户响应),但主要是 a1
或 a 0
(我感兴趣)。
所以我想将该表转置为一个新表survey
,以便返回的查询结果对于每一列都有相应的响应代码值作为列名(32 -> foot; 33 -> bike; 35 -> car
.etc)
我对所有这些回复不感兴趣,但对 5 : foot
, bike
(对于自行车)、bus
、car
和感兴趣metro
。
因为我很难只检索 5 个感兴趣的响应,所以我开始检索所有这些值,看看我是否正确地做事。事实证明我做错了。
这是我的尝试:
30 -- not_foot_count
31 -- not_moving
32 -- foot
33 -- bicycle
34 -- motorcycle
35 -- car
36 -- bus
37 -- metro
38 -- other
39 -- train
Run Code Online (Sandbox Code Playgroud)
这使:
SELECT * FROM survey;
session_id seconds not_foot_count not_moving foot bike motor car bus metro train other
758 1459505869 0 0 0 0 0 0 0 0 0 0
758 1459506973 0 0 0 0 0 0 0 0 0 0
758 1459508676 0 0 0 0 0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
请注意,这并不正确,因为该列car
应该是正确的1
。
此外,我对所有的价值观都不是不感兴趣。相反,只希望存在感兴趣的值。
预计出
我希望将我的返回结果限制为以下内容(带有正确答案):
session_id seconds foot bike car bus metro
758 1459505869 0 0 1 0 0
758 1459506973 0 0 1 0 0
758 1459508676 0 0 1 0 0
Run Code Online (Sandbox Code Playgroud)
注意:我的尝试在此dbfiddle中进行了说明。
编辑
就评论而言,问题已编辑以显示完整的预期输出。
小智 4
我不喜欢 crosstab() 函数,因为我发现它比过滤聚合更复杂(并且它不能解决您需要手动指定所有结果列的事实)。
以下返回您想要的内容。
select session_id,
seconds,
max(response) filter (where question_id = 32) as foot,
max(response) filter (where question_id = 33) as bike,
max(response) filter (where question_id = 36) as bus,
max(response) filter (where question_id = 35) as car,
max(response) filter (where question_id = 37) as metro
from response
group by session_id, seconds
Run Code Online (Sandbox Code Playgroud)