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.