Mysql 想要计算两个日期之间的工作日数

Mysql 想要计算两个日期之间的工作日数,mysql,datetime,Mysql,Datetime,我有一个开始和结束的日期 我想计算这两个日期之间的工作日数 然后在一张日期表中,我想以类似于只选择周末的方式计算这些日期 有人能帮我吗?一种方法是建立一个具体化的日期表。但用于构建这个物化表的方法也可以直接用于查询。我展示了几个[weekday]计算,但您可以使用相同的方法查询周末值5和6: 直接单查询示例: SELECT day , WEEKDAY(day) AS wkday FROM ( SELECT FROM_DAYS(d.day1+v1.result) AS day F

我有一个开始和结束的日期

我想计算这两个日期之间的工作日数

然后在一张日期表中,我想以类似于只选择周末的方式计算这些日期


有人能帮我吗?

一种方法是建立一个具体化的日期表。但用于构建这个物化表的方法也可以直接用于查询。我展示了几个[weekday]计算,但您可以使用相同的方法查询周末值5和6:

直接单查询示例:

SELECT day
     , WEEKDAY(day) AS wkday
  FROM (
SELECT FROM_DAYS(d.day1+v1.result) AS day
  FROM (SELECT TO_DAYS(DATE('2000-01-01')) AS day1
             , TO_DAYS(DATE('2021-01-01')) AS day2
     ) AS d
  JOIN (
      SELECT v1.num+v2.num+v3.num+v4.num AS result
        FROM (
                 SELECT 1 AS num UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
           UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0
           ) AS v1
        JOIN (
                 SELECT 10 AS num UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50
           UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90 UNION SELECT 00
           ) AS v2
        JOIN (
                 SELECT 100 AS num UNION SELECT 200 UNION SELECT 300 UNION SELECT 400 UNION SELECT 500
           UNION SELECT 600 UNION SELECT 700 UNION SELECT 800 UNION SELECT 900 UNION SELECT 000
           ) AS v3
        JOIN (
                 SELECT 1000 AS num UNION SELECT 2000 UNION SELECT 3000 UNION SELECT 4000 UNION SELECT 5000
           UNION SELECT 6000 UNION SELECT 7000 UNION SELECT 8000 UNION SELECT 9000 UNION SELECT 0000
           ) AS v4
     ) v1
 WHERE v1.result < (d.day2-d.day1)
     ) AS days
 WHERE WEEKDAY(day) < 5
 LIMIT 10
;



USE test;

DROP TABLE IF EXISTS days;

CREATE TABLE days (
   day   date PRIMARY KEY
) ENGINE = InnoDB;

INSERT INTO days
SELECT FROM_DAYS(d.day1+v1.result)
  FROM (SELECT TO_DAYS(DATE('2000-01-01')) AS day1
             , TO_DAYS(DATE('2021-01-01')) AS day2
     ) AS d
  JOIN (
      SELECT v1.num+v2.num+v3.num+v4.num AS result
        FROM (
                 SELECT 1 AS num UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
           UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0
           ) AS v1
        JOIN (
                 SELECT 10 AS num UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50
           UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90 UNION SELECT 00
           ) AS v2
        JOIN (
                 SELECT 100 AS num UNION SELECT 200 UNION SELECT 300 UNION SELECT 400 UNION SELECT 500
           UNION SELECT 600 UNION SELECT 700 UNION SELECT 800 UNION SELECT 900 UNION SELECT 000
           ) AS v3
        JOIN (
                 SELECT 1000 AS num UNION SELECT 2000 UNION SELECT 3000 UNION SELECT 4000 UNION SELECT 5000
           UNION SELECT 6000 UNION SELECT 7000 UNION SELECT 8000 UNION SELECT 9000 UNION SELECT 0000
           ) AS v4
     ) v1
 WHERE v1.result < (d.day2-d.day1)
;

SELECT *
  FROM days
 ORDER BY day
 LIMIT 10
;


SELECT COUNT(*) FROM days;

SELECT MIN(day), MAX(day) FROM days;

SELECT day, WEEKDAY(day) FROM days LIMIT 6;

SELECT day, WEEKDAY(day) AS wkday FROM days WHERE WEEKDAY(day) < 5 LIMIT 6;

SELECT COUNT(*), MIN(day), MAX(day) FROM days WHERE WEEKDAY(day) < 5;

这是一个使用MySql查找两个日期内的工作日数的简单查询:

set @d1='2013-09-25';
set @d2='2013-10-13';

select floor(datediff( @d2, @d1 ) / 7)*5 +
(case  when if(weekday(@d2)>=5,4,weekday(@d2))>=if(weekday(@d1)>=5,4,weekday(@d1)) 
then if(weekday(@d2)>=5,4,weekday(@d2))-if(weekday(@d1)>=5,4,weekday(@d1)) 
else 5+if(weekday(@d2)>=5,4,weekday(@d2))-if(weekday(@d1)>=5,4,weekday(@d1)) end) weekdays;
用PHP编写的相同算法:

function getWeekDays($d1,$d2){
$d1Array=preg_split('/-/',$d1);
$d2Array=preg_split('/-/',$d2);
$d1w=date('w',mktime(0,0,0,$d1Array[1],$d1Array[2],$d1Array[0]));
$d1w=in_array($d1w,array(0,6))?4:$d1w-1;
$d2w=date('w',mktime(0,0,0,$d2Array[1],$d2Array[2],$d2Array[0]));
$d2w=in_array($d2w,array(0,6))?4:$d2w-1;

$fullWeekDays=floor(((mktime(0,0,0,$d2Array[1],$d2Array[2],$d2Array[0])-mktime(0,0,0,$d1Array[1],$d1Array[2],$d1Array[0]))/86400)/7)*5;
$offset=$d2w>=$d1w?($d2w-$d1w):(5+$d2w-$d1w);
$weekDays=$fullWeekDays+$offset;

return $weekDays;
}

在给定2个日期的查询中是否可以完全执行此操作?我觉得为这个创建一个表有点太多了。我知道有一个datediff会在两天的约会中得到差异,我不确定是否有一种方法可以说是一天减去周末或者其他什么。在一个查询中有几种方法可以做到这一点。您可以将上述内容用作派生表或直接在视图中使用,而不是创建基表。然后可以在查询中使用该派生表或视图。这很简单,记住,派生表中的day是日期类型。您只需在外部查询的WHERE子句中添加一个测试,即可获得相关日期:“somedate”和“anotherdate”之间的WHERE day