PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie kann ich nur die Arbeitszeit von Reservierungen in PostgreSql zurückgeben?

Sie können die Funktion generate_series() verwenden, um außerhalb der Geschäftszeiten zu maskieren:

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

Lassen Sie mich einige knifflige Teile erklären:

  • Sie müssen keine Daten für Sa/So in pyha einfügen Tabelle, da Sie date_part('dow', d) verwenden können Funktion. Verwenden Sie pyha Tisch nur an Feiertagen. 'dow' gibt 0 oder 6 für So bzw. Sa zurück.
  • Feiertage und Sa/So können als Einzelintervall (0..24) dargestellt werden. Wochentage müssen durch zwei Intervalle (0..8) und (18..24) dargestellt werden, also unsest() und array[]
  • Sie können das Startdatum und die Länge in der Funktion generate_series() angeben

Basierend auf Ihrer Aktualisierung der Frage habe ich ein weiteres when hinzugefügt zu case :

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

Die Idee ist, verschiedene Intervalle für das Startdatum zu erzeugen (d::date = '2012-11-14'). ):(0..9) und (18..24)