Skip to content

Instantly share code, notes, and snippets.

@Mopip77
Created August 24, 2023 02:45
Show Gist options
  • Save Mopip77/cdeb377e84056b9e197750c29ea0e7e1 to your computer and use it in GitHub Desktop.
Save Mopip77/cdeb377e84056b9e197750c29ea0e7e1 to your computer and use it in GitHub Desktop.
mysql计算两个时间间隔/秒,排除周末

纯sql实现mysql计算两个时间的时间间隔,排除周末。其实就是计算工作日的实际用时(这里不涉及节假日)。

实现思路

假设起始时间是 start_time, 结束时间是 end_time

将起始时间到结束时间这个时间窗口分成四部分

  • 完整的x周(x>=0)
  • 一周内的天数
  • 起始时间到起始日期那天24点的用时
  • 结束日期0点到结束时间的用时
-- 完整的x周 * 5天工作日
5 * (DATEDIFF(end_time, start_time) DIV 7)

-- 一周内的天数
-- 这里的方式比较粗暴,穷举所有起始周几到结束周几的情况,输出固定的天数
MID('0123444401233334012222340111123400001234000123440',7*WEEKDAY(start_time)+WEEKDAY(end_time)+1,1))

-- 起始时间到起始日期那天24点的用时
-- 只有周一到周五才需要计算
IF (
   WEEKDAY(start_time) <= 4, 
   86400 - TIMESTAMPDIFF(SECOND, DATE(start_time), start_time),
   0
)

-- 结束那天时间同理计算
IF (
   WEEKDAY(end_time) <= 4, 
   TIMESTAMPDIFF(SECOND, DATE(end_time), end_time),
   0
)

最终SQL

SELECT
    (
       86400 * (5 * (DATEDIFF(end_time, start_time) DIV 7) 
       + MID('0123444401233334012222340111123400001234000123440',7*WEEKDAY(start_time)+WEEKDAY(end_time)+1,1))
       + 
       IF (
         WEEKDAY(start_time) <= 4, 
         86400 - TIMESTAMPDIFF(SECOND, DATE(start_time), start_time),
         0
       )
      +
       IF (
         WEEKDAY(end_time) <= 4, 
         TIMESTAMPDIFF(SECOND, DATE(end_time), end_time),
         0
       )
       -
       -- 通过上面的计算方式,如果起始日期和结束日期有一天是周末,都会导致多计算出来一天,需要在这里减去
       IF (
         WEEKDAY(start_time) in (5,6) or WEEKDAY(end_time) in (5,6),
         0,
         86400
       )
   ) as spent_time
FROM
  table_xx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment