I am using PostgreSQL 9.6 and have following schema
CREATE TABLE activitylog (
sessionid text NOT NULL,
studentid integer NOT NULL,
activity text NOT NULL,
created timestamp without time zone DEFAULT now() NOT NULL
);
The schema is used to log visitors activity. Each visit is assigned a session id which is unique for the visit. Sessions ends when user logs out. Every user can log in and log out multiple times.
INSERT INTO activitylog VALUES
( 'abc', 1, 'logged in' , '2017-08-12T02:39:05.753088Z' ),
( 'abc', 1, 'page visited', '2017-08-12T02:49:05.753088Z' ),
( 'abc', 1, 'logged out' , '2017-08-12T02:59:05.753088Z' ),
( 'def', 1, 'logged in' , '2017-08-12T03:09:05.753088Z' ),
( 'def', 1, 'page visited', '2017-08-12T03:19:05.753088Z' ),
( 'def', 1, 'logged out' , '2017-08-12T03:29:05.753088Z' ),
( 'ghi', 2, 'logged in' , '2017-08-12T03:39:05.753088Z' ),
( 'ghi', 2, 'page visited', '2017-08-12T03:59:05.753088Z' ),
( 'ghi', 2, 'logged out' , '2017-08-12T03:59:05.753088Z' );
Required Result
I want to select data from the table such that I get result in following format
| sessionid | studentid | loggedin | loggedout | interval |
| ----------- | ----------- | -------------- | ----------- | ------------------ |
| abc | 1 | 2017-08-12T02:39:05.753088Z | 2017-08-12T02:59:05.753088Z | 20min |
| def | 1 | 2017-08-12T03:09:05.753088Z | 2017-08-12T03:29:05.753088Z | 20min |
| ghi | 2 | 2017-08-12T03:39:05.753088Z | 2017-08-12T03:59:05.753088Z | 20min |
Basically,
- Pivot table
- Add studentid column
- Calculate interval
What I have tried so far
I have successfuly piovoted the table
SELECT * FROM crosstab(
$$
select sessionid, activity, created from activitylog
where activity = 'logged in' OR activity = 'logged out'
ORDER BY 1, 2
$$
)
AS sessioninfo (sessionid text, loggedin timestamp, loggedout timestamp);

I tried to add studentid extra column using this query but it didn't give me desired result
SELECT * FROM crosstab(
$$
select sessionid, studentid, activity, created from
activitylog
where activity = 'logged in' OR activity = 'logged out'
ORDER BY 1, 2
$$,
$$
VALUES (1), (0)
$$
)
AS sessioninfo (sessionid text, studentid INTEGER,
loggedin timestamp, loggedout timestamp);
But this places null in logged in and logged out timestamps.

To sum it up
- What is the purpose of
VALUESwithcrosstab()? To be honest I am not completely sure what purpose second parameter ofcrosstab()serves and why in almost all examples it isVALUES. - How do I add
studentidto result? - How do I calculate interval between two columns that are result of
crosstab()?
VALUEScould have sat on its own on the site. The more atomic the question the better. If you're happy with the answer, don't forget to mark it as chosen. – Evan Carroll Sep 07 '17 at 22:41