sql >> Database teknologi >  >> RDS >> PostgreSQL

Tidsforskel indenfor åbningstid

Jeg vil foreslå, at du genererer alle åbningstider mellem created_at og aktuelle_tidsstempel og summering af dem. Selvom det er langt fra optimal løsning med hensyn til ydeevne, synes jeg, det er den mest ligetil tilgang. Jeg bruger tidsstempel med tidszoneområde tstzrange med vejkryds 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 opsætningen og eksemplet i db<>fiddle

Advarsel

Selvom implementeringen er lavet til at være nem at forstå og fejlfinde, kan den resultere i dårlig ydeevne - især hvis den bruges med meget gamle oprettede_at-datoer. Hvis det kan være tilfældet i dit system, kan du være bedre stillet til at skrive en funktion, der kontrollerer ugedagen for oprettet_at og nuværende_dato, finder antallet af dage imellem dem og bestemmer arbejdstiden.




  1. Radius på 40 kilometer ved brug af bredde- og længdegrad

  2. BITAND() Funktion i Oracle

  3. Hvordan formindsker man temp tablespace i Oracle?

  4. Sådan sætter du en værdi i flere kategorier