I have this table in my PostgreSQL:
CREATE TABLE visits(
id BIGSERIAL NOT NULL PRIMARY KEY,
timeslot TSRANGE NOT NULL,
user_id INTEGER NOT NULL REFERENCES users(id),
CONSTRAINT overlapping_timeslots EXCLUDE USING GIST (
user_id WITH =,
timeslot WITH &&
));
With this Data:
| id | timeslot | user_id |
| 1 | 10.02.2014 10:00 - 10.02.2014 17:00 | 2 |
| 2 | 10.02.2014 18:00 - 10.02.2014 19:00 | 2 |
| 3 | 11.02.2014 01:00 - 11.02.2014 02:00 | 2 |
| 4 | 10.02.2014 12:00 - 11.02.2014 17:00 | 2 |
| 5 | 11.02.2014 12:00 - 11.02.2014 12:30 | 2 |
I need to know how many users are visted my shop every day. If a user visits the shop twice a day it should be count twice.
In the example above it should be.
Users at 10.02 = 3 (ID: 1,2,4)
Users at 11.02 = 3 (ID: 3,4,5)
Assuming an arbitrary period of time for lack of definition for "every day":
SELECT day, count(*) AS visits, array_agg(id) AS ids
FROM generate_series ('2014-02-10'::date
, '2014-02-12'::date
, interval '1 day') AS d(day)
JOIN visits ON tsrange(day::timestamp
, day::timestamp + interval '1 day') && timeslot
GROUP BY 1;
&&
is the "overlap" operator for range types.
Use a LEFT JOIN
to include days with 0 visits in the result.