HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

What am I missing in my crosstab query here?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
herewhatquerycrosstabmissing

Problem

I am having difficulty understanding how to correctly transpose this table from a database I am using. This table was created by someone who designed the database years ago, but I managed to retrieve the table's create statement using pg_dump.

Here's the table with an example entry:
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]


The question id in the question_id column stands for the following:

30  -- not_foot_count 
31  -- not_moving
32  -- foot
33  -- bicycle
34  -- motorcycle
35  -- car
36  -- bus
37  -- metro
38  -- other
39  -- train


Response can be text (wrong user response), but mostly a 1 or a 0 (which are of interest to me).

So I want to transpose this table into a new table survey, so that the

Solution

I am not a fan of the crosstab() function as I find it more complicated than filtered aggregation (and it doesn't workaround the fact that you need to specify all result columns manually).

The following returns what you want.

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

Code Snippets

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

Context

StackExchange Database Administrators Q#317424, answer score: 4

Revisions (0)

No revisions yet.