在 Db2 中的查询中排除两个时间戳之间的周末

Exclude weekend between two timestamps in a query in Db2

我有两列,每列都有时间戳

column_a               column_b
2021-08-03 13:22:29    2021-08-09 15:51:59

我想计算小时差,但不包括周末(如果日期落在两个时间戳或两者之间)。

我试过 TIMESTAMPDIFF 和 HOURS_BETWEEN - 但这些仍然包括周末。

更新: 我的解决方案是...... 创建一个函数来计算两天之间的天数,不包括从这里获取的周末 How to get the WORKING day diff in db2 without saturdays and sundays?

然后在我的SELECT中使用了db2s原生的DATEDIFF(8,xxx,yyy)得到总小时数,并从这个DATEDIFF中减去函数返回的值*24(小时数)

WITH 
  MYTAB (A, B) AS 
  (
    VALUES ('2021-08-03 13:22:29'::TIMESTAMP, '2021-08-09 15:51:59'::TIMESTAMP)
  )
, MYTAB2 (A, B) AS 
(
SELECT 
  CASE WHEN DAYOFWEEK(A) IN (1, 7) THEN DATE (A) + 1 DAY ELSE A END 
, CASE WHEN DAYOFWEEK(B) IN (1, 7) THEN B - (MIDNIGHT_SECONDS (B) + 1) SECOND ELSE B END  
FROM MYTAB
)
, R (TS) AS 
(
SELECT V.TS
FROM MYTAB2 T, TABLE (VALUES T.A, T.B) V (TS)
WHERE T.A <= T.B
  UNION ALL
SELECT DATE (R.TS) + 1 DAY 
FROM R, MYTAB2 T
WHERE DATE (R.TS) + 1 DAY < DATE (T.B)
)
SELECT
COALESCE
(
-- Seconds between start and end
  (DAYS (MAX (TS)) - DAYS (MIN (TS))) * 86400 
+ MIDNIGHT_SECONDS (MAX (TS)) - MIDNIGHT_SECONDS (MIN (TS))
-- SUM of seconds for weekend days is subtracted
- SUM (CASE WHEN DAYOFWEEK (TS) IN (1, 7) THEN 86400 ELSE 0 END)
, 0
) / 3600 AS HRS  
FROM R

思路是先用 Recursive Common Table 表达式构造以下 table:

2021-08-03 13:22:29 --> 2021-08-04 00:00:00 (if start is a weekend)
2021-08-04 00:00:00 --> 2021-08-05 00:00:00 (if start is a weekend)
...
2021-08-08 00:00:00 --> 2021-08-07 00:00:00 (if end is a weekend)
2021-08-09 15:51:59 --> 2021-08-08 23:59:59 (if end is a weekend)

即:开始时间戳和结束时间戳之间的每一天都有一个时间戳。这些开始和结束时间戳已调整:

  • 如果开始时间是周末 - 将其更改为第二天的开始时间
  • 如果结束时间是周末 - 将其更改为前一天结束时间

最后的计算很简单:我们从开始和结束之间的秒数差中减去列表中所有周末的秒数总和。