Saya sarankan untuk membuat semua rentang jam kerja antara created_at
dan current_timestamp dan menjumlahkannya. Meskipun jauh dari solusi optimal dalam hal kinerja, saya pikir ini adalah pendekatan yang paling mudah. Saya menggunakan cap waktu dengan rentang zona waktu tstzrange
dengan persimpangan 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
Lihat penyiapan dan contoh di db<>biola
Peringatan hati
Meskipun implementasi dibuat agar mudah dipahami dan di-debug, hal itu dapat menghasilkan kinerja yang buruk - terutama jika digunakan dengan tanggal create_at yang sangat lama. Jika itu yang terjadi di sistem Anda, Anda mungkin lebih baik menulis fungsi yang memeriksa hari dalam minggu dari create_at dan current_date, menemukan jumlah hari di antara mereka dan menentukan jam kerja.