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

时间:2012-10-17 00:10:38

标签: mysql datetime

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

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

然后在日期表中,我想以类似的方式计算那些只选择周末的人。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

一种方法是拥有一个物化日期/日期表。但是,用于构建此物化表的同一方法可以直接在查询中使用。我展示了几个[工作日]计算,但您可以使用相同的方法查询周末天数(周末日值为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;

答案 1 :(得分:1)

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

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;
}