PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да върна само работно време от резервации в PostgreSql?

Можете да използвате функцията 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

Нека обясня някои трудни части:

  • не е нужно да вмъквате дати за сб/слънце в pyha таблица, защото можете да използвате date_part('dow', d) функция. Използвайте pyha маса само за официални празници. 'dow' връща 0 или 6 съответно за слънце или събота.
  • официалните празници и събота/слънце могат да бъдат представени като единичен интервал (0..24). Дните от седмицата трябва да бъдат представени с два интервала (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)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на криптиране за засилване на сигурността на базата данни на PostgreSQL

  2. Набор на JDBCTemplate вложен POJO с BeanPropertyRowMapper

  3. PostgreSQL:Предупреждение:Кодовата страница на конзолата (437) се различава от кодовата страница на Windows (1252)

  4. Как да архивирате и възстановите PostgreSQL база данни чрез DBeaver

  5. Връщане на множество полета като запис в PostgreSQL с PL/pgSQL