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

Zeitverschiebung innerhalb der Geschäftszeiten

Ich würde vorschlagen, alle Bereiche der Geschäftszeiten zwischen created_at zu generieren und current_timestamp und deren Summierung. Obwohl es in Bezug auf die Leistung alles andere als eine optimale Lösung ist, denke ich, dass es der einfachste Ansatz ist. Ich verwende Zeitstempel mit Zeitzonenbereich tstzrange mit Schnittpunkt Operator (*) .

SELECT id,
  created_at,
  SUM(upper(business_range) - lower(business_range) ) business_hours
FROM (
  SELECT id, 
    created_at,
    tstzrange(date_in_range + '09:00'::time with time zone, date_in_range + '17:00'::time with time zone) 
      * tstzrange(created_at, current_timestamp) as business_range
  FROM (
    SELECT id,
      created_at,
      created_at::date + generate_series(0, current_timestamp::date - created_at::date) as date_in_range 
    FROM times
  ) dates_in_range
  WHERE date_part('dow', date_in_range) in (1,2,3,4,5)
) business_hour_ranges
GROUP BY
  id,
  created_at

Siehe Setup und Beispiel in db<>fiddle

Warnung

Obwohl die Implementierung so gestaltet wurde, dass sie leicht verständlich und debuggbar ist, kann sie zu einer schlechten Leistung führen – insbesondere, wenn sie mit sehr alten „created_at“-Daten verwendet wird. Wenn dies in Ihrem System der Fall sein kann, sollten Sie besser eine Funktion schreiben, die den Wochentag von "created_at" und "current_date" überprüft, die Anzahl der Tage zwischen ihnen ermittelt und die Arbeitszeit bestimmt.