I have 2 tables: availability
and blocked_availability
.
availability:
day | start | end |
---|---|---|
1 | 09:00 | 11:00 |
1 | 12:00 | 16:00 |
blocked_availabilty
day | start | end |
---|---|---|
1 | 09:30 | 10:30 |
1 | 12:30 | 14:30 |
From these 2 tables combined I would like to see if there’s a period of at least X minutes of availability.
In above example there some available timeslots:
09:00 – 09:30
10:30 – 11:00
12:00 – 12:30
14:30 – 16:00
Is there a query to see if there’s an available timeslot of at least 60 minutes (there’s only 1 in this example).
3
Answers
You can use a recursive
cte
to build timeslot intervals from the availability listings and thenleft join
the blocked availabilties to thecte
. Then, a ranking can performed on the rows that do not have a match in the blocked availabilities (thus it is available), and the rank values can be grouped on to find the total number of minutes per interval:See fiddle
Here’s an example query that you could use to find available timeslots of at least 60 minutes:
In this query,
X
is the minimum number of minutes for an available timeslot (in this case, 60 minutes).The query works by joining the
availability
table with itself to find pairs of time slots that are adjacent on the same day. TheLEFT JOIN
withblocked_availability
table excludes any time slots that overlap with blocked time slots. Finally, theWHERE
clause filters the results to include only time slots that are at least X minutes long and do not overlap with blocked time slots.Note that you’ll need to replace
X
with the number of minutes you want to check for, and adjust the table and column names as needed to match your schema.Unpivot values from both tables (here done with union all), then use lead(). This produces all possible periods from your tables. Now you can join with original data, filter "blocked" periods and count time difference.
dbfiddle demo