Ik stel voor om alle bereiken van kantooruren te genereren tussen created_at
en current_timestamp en optellen. Hoewel het verre van optimale oplossing is in termen van prestaties, denk ik dat dit de meest ongecompliceerde benadering is. Ik gebruik een tijdstempel met tijdzonebereik tstzrange
met intersectie 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
Zie de setup en het voorbeeld in db<>fiddle
Waarschuwing
Hoewel de implementatie is gemaakt om gemakkelijk te begrijpen en te debuggen, kan dit resulteren in slechte prestaties - vooral als deze wordt gebruikt met zeer oude datums van gemaakt_op. Als dat het geval is in uw systeem, kunt u beter een functie schrijven die de dag van de week van de aangemaakte_at en huidige_datum controleert, het aantal dagen ertussen vindt en de werkuren bepaalt.