How to return only work time from reservations in PostgreSql?

限于喜欢 提交于 2019-11-29 07:36:54

You can use generate_series() function in order to mask-out non business hours:

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

Let me explain some tricky parts:

  • you dont have to insert dates for sat/sun into pyha table because you can use date_part('dow', d) function. Use pyha table for public holidays only. 'dow' returns 0 or 6 for Sun or Sat respectively.
  • public holidays and sat/sun can be represented as single interval (0..24). Weekdays have to be represented by two intervals (0..8) and (18..24) hence unnest() and array[]
  • you can specify start date and length in generate_series() function

Based on your update to the question I added another when to case:

when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]

The idea is to produce different interval(s) for starting date (d::date = '2012-11-14'): (0..9) and (18..24)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!