sql >> Database >  >> RDS >> PostgreSQL

Hoe kan ik alleen werktijd teruggeven van reserveringen in PostgreSql?

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 je date_part('dow', d) . kunt gebruiken functie. Gebruik pyha 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)




  1. Cloud Native en DevSecOps op schaal met Capgemini Agile Innovation Platform en Oracle Cloud

  2. 3 manieren om erachter te komen of een kolom een ​​berekende kolom is in SQL Server

  3. Oracle krijgt externe sleutels

  4. SQL Server - Beste manier om de identiteit van de ingevoegde rij te krijgen?