created_at
の間のすべての営業時間範囲を生成することをお勧めします そしてcurrent_timestampとそれらを合計します。パフォーマンスの点では最適なソリューションにはほど遠いですが、最も簡単なアプローチだと思います。タイムゾーン範囲が tstzrange
交差点がある
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
db <>fiddle のセットアップと例を参照してください。
注意事項
実装は理解とデバッグが容易になるように作成されていますが、特に非常に古いcreated_at日付で使用すると、パフォーマンスが低下する可能性があります。システムに当てはまる場合は、created_atとcurrent_dateの曜日をチェックし、それらの間の日数を見つけて稼働時間を決定する関数を作成する方がよい場合があります。