WITH validities AS ( SELECT validity, lower( validity ) AS validity_begin, upper( validity ) AS validity_end FROM ( SELECT DISTINCT validity FROM bookings.routes ) AS validities ), dates AS ( SELECT validity, tz, dt::date, extract( isodow FROM dt ) AS dow, validity_begin, validity_end FROM validities v CROSS JOIN ( SELECT DISTINCT timezone FROM bookings.airports ) tz(tz) CROSS JOIN generate_series( timezone( tz, v.validity_begin )::date::timestamp, timezone( tz, v.validity_end )::date::timestamp, '1 day'::interval ) dt ), schedules AS ( SELECT r.route_no, a.timezone AS tz, r.validity, r.scheduled_time, unnest( r.days_of_week ) AS dow FROM bookings.routes r JOIN bookings.airports a ON a.airport_code = r.departure_airport ), dates_to_be AS ( SELECT s.route_no, s.tz, s.validity, s.dow, timezone( s.tz, d.dt + s.scheduled_time ) AS scheduled_dep FROM schedules s JOIN dates d ON d.validity = s.validity AND d.tz = s.tz AND d.dow = s.dow WHERE timezone( s.tz, d.dt + s.scheduled_time ) >= d.val