U kunt de functie Genereer_serie() gebruiken om niet-kantooruren te maskeren:
with gaps as (
select
upper(during) as start,
lead(lower(during),1,upper(during)) over (ORDER BY during) - upper(during) as gap
from (
select during
from reservation
union all
select
unnest(case
when pyha is not null then array[tsrange(d, d + interval '1 day')]
when date_part('dow', d) in (0, 6) then array[tsrange(d, d + interval '1 day')]
when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
else array[tsrange(d, d + interval '8 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
end)
from generate_series(
'2012-11-14'::timestamp without time zone,
'2012-11-14'::timestamp without time zone + interval '2 week',
interval '1 day'
) as s(d)
left join pyha on pyha = d::date
) as x
)
select *
from gaps
where gap > '0'::interval
order by start
Laat me een paar lastige onderdelen uitleggen:
- je hoeft geen datums voor zat/zon in te voegen in
pyha
tabel omdat jedate_part('dow', d)
. kunt gebruiken functie. Gebruikpyha
tafel alleen op feestdagen. 'dow' geeft 0 of 6 terug voor respectievelijk zon of za. - feestdagen en za/zo kunnen worden weergegeven als een enkel interval (0..24). Weekdagen moeten worden weergegeven met twee intervallen (0..8) en (18..24) vandaar unnest() en array[]
- u kunt de startdatum en lengte specificeren in de functie Genereer_serie()
Op basis van je update van de vraag heb ik nog een when
. toegevoegd naar case
:
when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
Het idee is om verschillende interval(s) voor de startdatum te produceren (d::date = '2012-11-14'
):(0..9) en (18..24)