営業時間外をマスクアウトするために、generate_series()関数を使用できます。
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
トリッキーな部分をいくつか説明しましょう:
- sat/sunの日付を
pyha
に挿入する必要はありませんdate_part('dow', d)
を使用できるためテーブル 働き。pyha
を使用する 祝日のみのテーブル。 'dow'は、SunまたはSatに対してそれぞれ0または6を返します。 - 祝日と土/日は単一の間隔(0..24)として表すことができます。平日は2つの間隔(0..8)と(18..24)で表す必要があるため、unnest()とarray []
- generate_series()関数で開始日と長さを指定できます
質問に対するあなたの更新に基づいて、私は別のwhen
を追加しました case
へ :
when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
アイデアは、開始日に対して異なる間隔を生成することです(d::date = '2012-11-14'
):(0..9)および(18..24)