mysql - 两个日期之间的工作日数[逻辑]

标签 mysql

我有一个函数是 MySql,它计算两个给定日期之间的工作日期数,但我想知道其中使用的逻辑。 sql函数如下:

 CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
 RETURNS INT
 RETURN ABS(DATEDIFF(date2, date1)) + 1
 - ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
 - (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
 - (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);

最佳答案

ABS(DATEDIFF(date2, date1)) + 1
 - ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
 - (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
 - (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
 ;    

ABS 用于确保每个结果都是正整数,以防日期向后(如果起点在终点之后)。

ABS(DATEDIFF(date2, date1)) + 1

DATEDIFF 返回 2 个日期时间值的 dates 之间的日历天数(实际上将两者的时间设置为 00:00:00+00000日期)。因为 DATEDIFF 使用日期,只有第二天的 duration 丢失,所以加 1 进行补偿。

 - ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2

使用 ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY)ADDDATE(date1, INTERVAL 1) 计算两个日期的一周开始 - DAYOFWEEK(date1) DAY) 然后获取这些日期之间的天数。将该数字除以 7 得到日期之间跨越的周数。将该数字乘以 2 得到跨度中涉及的周末天数。从先前计算的原始天数中减去这些周末天数,得出日期之间的工作日总数。

然而,给定的开始/结束日期时间可能单独在周末,所以:

 - (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)

如果给定日期之一是星期日,则减去 1

 - (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)

如果给定日期之一是星期六,则减去 1

得出工作周不包括周六和周日的“工作日”数。


如果您感兴趣,这里有一个查询将每个函数或函数调用集分解为单独的列,以便您可以对其进行跟踪。调整提供 2 个日期的子查询以适应。

select
  date1
, date2
, DATEDIFF(date2, date1)      "datediff"
, ABS(DATEDIFF(date2, date1)) abs_datediff
, ABS(DATEDIFF(date2, date1)) + 1 diff_2end_dt
, DAYOFWEEK(date2)                dt2_dow
, ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY) start_of_wk_dt2
, DAYOFWEEK(date1) dt1_dow
, ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY) start_of_wk_dt1
, DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)) diff_wksby7
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) abs_diff_wksby7               
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
                ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2 diff_wkends
, DAYOFWEEK(IF(date1 < date2, date1, date2)) dow_min
, DAYOFWEEK(IF(date1 > date2, date1, date2)) dow_max

from (
    select date_add(now(), INTERVAL -34 DAY) as date1, date_add(now(), INTERVAL -2 DAY) as date2
    ) d

关于mysql - 两个日期之间的工作日数[逻辑],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46726897/

相关文章:

php - 我想将两列合并为一个新列,但前提是其中一列不为空,然后按该新列排序。 (MySQL)

mysql - 如何动态地将数据传递给mysql查询

MySql:将 float 转换为十进制数会产生比存储在 back.sql 文件中更多的十进制数

php - 我应该使用 UNION 还是其他方式从多个表中选择数据?

MySQL 与 Docker/Kubernetes

mysql删除最后一个字符

mysql - 为 Flyway 'schema_version' 表设置 mysql 引擎

mysql - 为什么我无法将数据插入数据库

python - 操作数应包含 1 列有关插入和选择的内容

mysql - 嵌套 GROUP BY 优化