sql >> Databáze >  >> RDS >> PostgreSQL

Časový rozdíl v pracovní době

Navrhoval bych vygenerovat všechny rozsahy pracovní doby mezi created_at a aktuální_časové razítko a jejich sečtením. I když to není zdaleka optimální řešení z hlediska výkonu, myslím, že je to nejpřímější přístup. Používám časové razítko s rozsahem časového pásma rozsah tstz s křižovatkou operátor (*) .

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

Viz nastavení a příklad v db<>fiddle

Upozornění

I když byla implementace navržena tak, aby byla snadno srozumitelná a laditelná, může mít za následek špatný výkon – zejména při použití s ​​velmi starými daty created_at. Pokud to tak může být ve vašem systému, může být lepší napsat funkci, která zkontroluje den v týdnu v created_at a current_date, zjistí počet dní mezi nimi a určí pracovní hodiny.




  1. Jaký je nejúčinnější způsob uložení pořadí řazení ve skupině záznamů v databázi?

  2. SQLite ALTER TABLE

  3. Volání funkce s uživatelem definovanými parametry typu (Oracle ODP.NET)

  4. Umožňuje uživatelům vybírat z tabulky