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

Mysql 两个日期之间的工作日数[逻辑],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), AD

我有一个函数是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);
CREATE FUNCTION TOTAL_工作日(date1日期、date2日期)
返回整数
返回ABS(DATEDIFF(date2,date1))+1
-ABS(DATEDIFF)(ADDDATE(date2,间隔1-DAYOFWEEK(date2)天),
ADDDATE(date1,间隔1-DAYOFWEEK(date1)DAY))/7*2
-(DAYOFWEEK(如果(date1date2,date1,date2))=7;
DATEDIFF
返回两个日期时间值的日期之间的日历天数整数(实际上,将两个日期的时间设置为00:00:00+00000)。由于
DATEDIFF
只使用日期,因此第二天的持续时间将丢失,因此添加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)
得出“工作日”数,其中工作周不包括周六和周日


如果您感兴趣,这里有一个查询,它将每个函数或函数调用集分解为单独的列,以便您可以跟踪每个列。调整提供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
选择
日期1
,日期2
,DATEDIFF(date2,date1)“DATEDIFF”
,ABS(DATEDIFF(date2,date1))ABS_DATEDIFF
,ABS(DATEDIFF(date2,date1))+1 diff\u 2end\u dt
,星期二(日期2)dt2_dow
,ADDDATE(日期2,间隔1-工作日(日期2)天)开始工作日期2
,星期一(日期1)dt1_dow
,ADDDATE(日期1,间隔1-工作日(日期1)天)开始工作日期1
,DATEDIFF(ADDDATE(日期2,间隔1-DAYOFWEEK(日期2)天),
ADDDATE(日期1,间隔1-星期几(日期1)天))差异工作日7
,ABS(DATEDIFF)(ADDDATE(date2,间隔1-DAYOFWEEK(date2)天),
ADDDATE(日期1,间隔1-星期几(日期1)天))abs_diff_wksby7
,ABS(DATEDIFF)(ADDDATE(date2,间隔1-DAYOFWEEK(date2)天),
ADDDATE(date1,间隔1-DAYOFWEEK(date1)DAY))/7*2个不同的工作日
,星期一(如果(日期1<日期2,日期1,日期2))道明
,DAYOFWEEK(如果(date1>date2,date1,date2))道琼斯指数
从(
选择日期添加(现在(),间隔-34天)作为日期1,选择日期添加(现在(),间隔-2天)作为日期2
)d

谢谢。这篇文章真的帮助我理解了。(Y)
 - (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
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