首頁 > 資料庫 > mysql教程 > 如何計算 PostgreSQL 中日期之間的工作時間(考慮週末和特定工作時間)?

如何計算 PostgreSQL 中日期之間的工作時間(考慮週末和特定工作時間)?

Patricia Arquette
發布: 2025-01-03 10:35:40
原創
423 人瀏覽過

How Can I Calculate Working Hours Between Dates in PostgreSQL, Considering Weekends and Specific Working Hours?

計算PostgreSQL 中日期之間的工作時間

簡介

在各種場景中,確定兩個時間戳之間的工作小時數在工資單和調度等領域被證明是至關重要的。在 PostgreSQL 中,此計算需要仔細考慮工作日和特定時間的參數。本文概述了一個全面的解決方案,考慮到以下標準:

  • 週末(週六和週日) 不計入工作時間。
  • 工作時間定義為週一至週五,上午 8 點至凌晨 3 點pm.
  • 小數小時將包含在計算中。

解決方案

方法1:四捨五入僅兩個時間戳的結果

此方法適用於以1 小時為單位,忽略小數小時。這是一種簡單但不太精確的方法。

查詢:

SELECT count(*) AS work_hours
FROM   generate_series (timestamp '2013-06-24 13:30'
                      , timestamp '2013-06-24 15:29' - interval '1h'
                      , interval '1h') h
WHERE  EXTRACT(ISODOW FROM h) < 6
AND    h::time >= '08:00'
AND    h::time &amp;lt;= '14:00';
登入後複製

範例輸入:

2013-06-24 13:30, 2013-06-24 15:29
登入後複製

輸出:

2
登入後複製

方法2:時間戳表的捨入結果

這種方法擴展了先前的方法來處理時間戳表

查詢:
SELECT t_id, count(*) AS work_hours
FROM  (
   SELECT t_id, generate_series (t_start, t_end - interval '1h', interval '1h') AS h
   FROM   t
   ) sub
WHERE  EXTRACT(ISODOW FROM h) < 6
AND    h::time >= '08:00'
AND    h::time <= '14:00'
GROUP  BY 1
ORDER  BY 1;
登入後複製

方法三:更精確的計算

對於較細微的計算,較小的時間單位可以是已考慮。

查詢:
SELECT t_id, count(*) * interval '5 min' AS work_interval
FROM  (
   SELECT t_id, generate_series (t_start, t_end - interval '5 min', interval '5 min') AS h
   FROM   t
   ) sub
WHERE  EXTRACT(ISODOW FROM h) < 6
AND    h::time >= '08:00'
AND    h::time <= '14:55'
GROUP  BY 1
ORDER  BY 1;
登入後複製

範例輸入:
| t_id | t_start                | t_end                  |
|------|-------------------------|-------------------------|
| 1    | 2009-12-03 14:00:00    | 2009-12-04 09:00:00    |
| 2    | 2009-12-03 15:00:00    | 2009-12-07 08:00:00    |
| 3    | 2013-06-24 07:00:00    | 2013-06-24 12:00:00    |
| 4    | 2013-06-24 12:00:00    | 2013-06-24 23:00:00    |
| 5    | 2013-06-23 13:00:00    | 2013-06-25 11:00:00    |
| 6    | 2013-06-23 14:01:00    | 2013-06-24 08:59:00    |
登入後複製

輸出:
| t_id | work_interval |
|------|----------------|
| 1    | 1 hour         |
| 2    | 8 hours        |
| 3    | 0 hours        |
| 4    | 0 hours        |
| 5    | 6 hours        |
| 6    | 1 hour         |
登入後複製

方法4:精確結果

此方法提供微秒精度的精確結果。它更複雜,但計算效率更高。

WITH var AS (SELECT '08:00'::time  AS v_start
                  , '15:00'::time  AS v_end)
SELECT t_id
     , COALESCE(h.h, '0')  -- add / subtract fractions
       - CASE WHEN EXTRACT(ISODOW FROM t_start) < 6
               AND t_start::time > v_start
               AND t_start::time < v_end
         THEN t_start - date_trunc('hour', t_start)
         ELSE '0'::interval END
       + CASE WHEN EXTRACT(ISODOW FROM t_end) < 6
               AND t_end::time > v_start
               AND t_end::time < v_end
         THEN t_end - date_trunc('hour', t_end)
         ELSE '0'::interval END                 AS work_interval
FROM   t CROSS JOIN var
LEFT   JOIN (  -- count full hours, similar to above solutions
   SELECT t_id, count(*)::int * interval '1h' AS h
   FROM  (
      SELECT t_id, v_start, v_end
           , generate_series (date_trunc('hour', t_start)
                            , date_trunc('hour', t_end) - interval '1h'
                            , interval '1h') AS h
      FROM   t, var
      ) sub
   WHERE  EXTRACT(ISODOW FROM h) < 6
   AND    h::time >= v_start
   AND    h::time <= v_end - interval '1h'
   GROUP  BY 1
   ) h USING (t_id)
ORDER  BY 1;
登入後複製

查詢:

這個全面的解決方案解決了在 PostgreSQL 中準確高效地計算工作時間的需求。

以上是如何計算 PostgreSQL 中日期之間的工作時間(考慮週末和特定工作時間)?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板