sql >> Databasteknik >  >> RDS >> PostgreSQL

Tidsskillnad inom kontorstid

Jag skulle föreslå att du genererar alla intervall för öppettider mellan created_at och aktuell_tidsstämpel och summera dem. Även om det är långt ifrån optimal lösning när det gäller prestanda, tror jag att det är det mest enkla tillvägagångssättet. Jag använder tidsstämpel med tidszonintervall tstzrange med korsning operatör (*) .

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

Se inställningen och exemplet i db<>fiol

Varning

Även om implementeringen gjordes för att vara lätt att förstå och felsöka kan den resultera i dålig prestanda - speciellt om den används med mycket gamla create_at-datum. Om så kan vara fallet i ditt system kan det vara bättre för dig att skriva en funktion som kontrollerar veckodagen för create_at och current_date, hittar antalet dagar mellan dem och bestämmer arbetstimmar.




  1. Hur räknar man rader från två tabeller i en fråga?

  2. Ta bort alla nolldatum från MySQL-databasen i alla tabeller

  3. Är det korrekt att skanna en tabell i MySQL med SELECT * .. Limit start, räknas utan en ORDER BY-sats?

  4. Omvandlar godtyckligt många rader till kolumner i PostgreSQL