【问题标题】:Exclude weekend between two timestamps in a query in Db2在 Db2 中的查询中排除两个时间戳之间的周末
【发布时间】:2021-09-21 06:33:48
【问题描述】:

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

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(小时)

【问题讨论】:

  • 你的周末有多长?你试过减法吗?您可以使用 DAYOFWEEK 来确定给定的时间戳是否在周末。
  • 周末是周六和周日。 column_a 和 column_b 中的时间戳值将永远变化。有时时间戳可能落在我可以使用 DAYOFWEEK 的值上,有时周末可能在 column_a 到 column_b 范围的中间,以及其他各种组合。
  • 您所说的是,它归结为您可以实现的简单 IF / ELSE (=> CASE) 逻辑。试一试并报告。
  • 最大的区别是什么(可能是 30 天,其中可能包括多个周末日?国家法定节假日呢?要复杂得多。

标签: db2


【解决方案1】:
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

思路是先用递归公用表表达式构造下表:

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)

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

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

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

【讨论】:

  • 感谢一百万 @Mark !!
猜你喜欢
  • 2022-01-01
  • 2018-12-26
  • 1970-01-01
  • 2014-01-28
  • 2017-11-27
  • 1970-01-01
  • 2020-04-17
  • 2019-01-04
  • 1970-01-01
相关资源
最近更新 更多