计算两个日期之间的天数,不包括周末(仅限MySQL)

时间:2012-03-18 11:27:55

标签: mysql date datediff weekend

我需要计算MySQL中两个日期之间的差异(以天为单位),不包括周末(周六和周日)。也就是说,天数的差异减去周六和周日的数量。

目前,我只使用以下方式计算日期:

SELECT DATEDIFF('2012-03-18', '2012-03-01')

返回17,但我想排除周末,所以我想12(因为第3和第4,第10和第11和第17是周末的日子)。

我不知道从哪里开始。我知道WEEKDAY()函数和所有相关函数,但我不知道如何在这种情况下使用它们。

5 个答案:

答案 0 :(得分:8)

只需使用简单的功能尝试:

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

测试:

SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1,
       TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2;

结果:

| WEEKDAYS1 | WEEKDAYS2 |
-------------------------
|        13 |        13 |

答案 1 :(得分:4)

插图:

mtwtfSSmtwtfSS
  123456712345   one week plus 5 days, you can remove whole weeks safely
  12345-------   you can analyze partial week's days at start date
  -------12345   or at ( end date - partial days )

伪代码:

@S          = start date
@E          = end date, not inclusive
@full_weeks = floor( ( @E-@S ) / 7)
@days       = (@E-@S) - @full_weeks*7   OR (@E-@S) % 7

SELECT
  @full_weeks*5 -- not saturday+sunday
 +IF( @days >= 1 AND weekday( S+0 )<=4, 1, 0 )
 +IF( @days >= 2 AND weekday( S+1 )<=4, 1, 0 )
 +IF( @days >= 3 AND weekday( S+2 )<=4, 1, 0 )
 +IF( @days >= 4 AND weekday( S+3 )<=4, 1, 0 )
 +IF( @days >= 5 AND weekday( S+4 )<=4, 1, 0 )
 +IF( @days >= 6 AND weekday( S+5 )<=4, 1, 0 )
 -- days always less than 7 days

答案 2 :(得分:1)

Below function will give you the Weekdays, Weekends, Date difference with proper results:

You can call the below function like,
select getWorkingday('2014-04-01','2014-05-05','day_diffs');
select getWorkingday('2014-04-01','2014-05-05','work_days');
select getWorkingday('2014-04-01','2014-05-05','weekend_days');




    DROP FUNCTION IF EXISTS PREPROCESSOR.getWorkingday;
    CREATE FUNCTION PREPROCESSOR.`getWorkingday`(d1 datetime,d2 datetime, retType varchar(20)) RETURNS varchar(255) CHARSET utf8
    BEGIN
     DECLARE dow1, dow2,daydiff,workdays, weekenddays, retdays,hourdiff INT;
        declare newstrt_dt datetime;
       SELECT dd.iDiff, dd.iDiff - dd.iWeekEndDays AS iWorkDays, dd.iWeekEndDays into daydiff, workdays, weekenddays
      FROM (
       SELECT
         dd.iDiff,
         ((dd.iWeeks * 2) + 
          IF(dd.iSatDiff >= 0 AND dd.iSatDiff < dd.iDays, 1, 0) + 
          IF (dd.iSunDiff >= 0 AND dd.iSunDiff < dd.iDays, 1, 0)) AS iWeekEndDays
           FROM (
          SELECT  dd.iDiff, FLOOR(dd.iDiff / 7) AS iWeeks, dd.iDiff % 7 iDays, 5 - dd.iStartDay AS iSatDiff,  6 - dd.iStartDay AS iSunDiff
         FROM (
          SELECT
            1 + DATEDIFF(d2, d1) AS iDiff,
            WEEKDAY(d1) AS iStartDay
          ) AS dd
        ) AS dd
      ) AS dd ;
      if(retType = 'day_diffs') then
      set retdays = daydiff; 
     elseif(retType = 'work_days') then
      set retdays = workdays; 
     elseif(retType = 'weekend_days') then  
      set retdays = weekenddays; 
     end if; 
        RETURN retdays; 
        END;


Thank You.
Vinod Cyriac.
Bangalore

答案 3 :(得分:1)

我对你有帮助

波纹管逻辑仅显示多少天 喜欢

sun   mon

1      2 .....................

DELIMITER $$
DROP FUNCTION IF EXISTS `xx`.`get_weekday` $$
CREATE FUNCTION `xx`.`get_weekday` (first_date date, last_date date, curr_week_day int) RETURNS INT
BEGIN
DECLARE days_tot int;
DECLARE whole_weeks int;
DECLARE first_day int;
DECLARE last_day int;
SET whole_weeks = FLOOR(DATEDIFF(last_date,first_date)/7) ;
SET first_day = WEEKDAY(first_date) ;
SET last_day = WEEKDAY(last_date)  ;
IF curr_week_day  BETWEEN first_day AND  last_day
           AND  last_day > first_day
           OR ( curr_week_day BETWEEN last_day AND first_day
           AND  last_day <  first_day  )
THEN SET days_tot = whole_weeks + 1;
ELSE SET days_tot = whole_weeks ;
END IF;
RETURN  days_tot;
END $$
DELIMITER ;

    SELECT
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 0) as mo,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 1) as tu,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 2) as we,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 3) as th,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 4) as fr,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 5) as sa,
      `xx`.`get_weekday` ('2009-01-01', '2009-07-20', 6) as su;

基于表格的查询

IP:

Weekday count
2        10
3         5


SELECT WEEKDAY( `req_date_time` ) AS weekday, COUNT( id ) AS id
FROM `ddd`
WHERE (
`req_date_time` >= '2014-12-01'
AND `req_date_time` <= '2014-12-31'
)
AND WEEKDAY( `req_date_time` ) != '1'
GROUP BY WEEKDAY( `req_date_time` ) 

答案 4 :(得分:0)

您也可以使用查询执行此操作,但您需要一个涵盖日期范围的日期表。无论如何,最好创建一个日期表,以便在所有项目中使用。

要创建日期表,您只需生成一长串日期(EXCEL是方便的方法,但还有其他方法)并将它们导入表格。然后,将这些日期与各种日期函数结合使用,以得出“星期几”,“月份”,“年份”等,并将所有内容保存到表中并附上日期,如下所示:

<强> tbl_dates

dates table

dow是我桌上的'星期几'。然后您的查询如下所示:

SELECT Count(theDate) AS numWeekDays
FROM tbl_dates
WHERE theDate >[startDate] And theDate <=[endDate] AND dow <> 1 AND dow <> 7;

在这种情况下,1和7分别是星期日,星期六(这是默认值),当然,如果你需要为许多startDate和endDate(s)计算它,你可以将它嵌套到另一个查询中。 )。