Reputation: 21
Currently I'm implementing data base using PostgreSQL. I have the following database(Hope that ER-diagram fully describes it)
What do you need to know about this database is that friend can take a rest and have a holiday that is presented in a holiday
table by friend's id
, start_date
and end_date
.
I want to create a PostgreSQL query that will find dates, when exactly N
friends had a holiday. I'm confused with iterating over period between start and end date.(Every solution that will help with this query is okay).
Example: assume holiday
table to have such a content
(1, '2012-05-23', '2012-05-27', 1)
(2, '2012-05-23', '2012-05-24', 2)
(3, '2012-05-24', '2012-05-26', 3)
Assume that friend
table contain these three friends.
The output for number of friends = 3
will be '2012-05-24'.
For number of friends = 2
will be ('2012-05-23', '2012-05-25', '2012-05-26').
Upvotes: 0
Views: 583
Reputation: 147196
You can use GENERATE_SERIES
to generate a list of all the dates between the earliest start_date
and the latest end_date
and then LEFT JOIN
that to holiday
to find all the friends who were on holiday on a given date. You can then count them and filter by the result. For example, to find the days on which 2 friends were on holiday:
SELECT dates.d AS "date", COUNT(*) AS num_on_holiday
FROM GENERATE_SERIES((SELECT MIN(start_date) FROM holiday),
(SELECT MAX(end_date) FROM holiday),
'1 day'::interval) dates(d)
LEFT JOIN holiday h ON dates.d BETWEEN h.start_date AND h.end_date
GROUP BY dates.d
HAVING COUNT(*) = 2
ORDER BY dates.d
Output:
date num_on_holiday
2012-05-23 00:00:00+01 2
2012-05-25 00:00:00+01 2
2012-05-26 00:00:00+01 2
Upvotes: 2