mysql函数计算两个日期之间的天数,不包括周末

标签 mysql

我搜索了很多例子,我找到了很好的例子:

  1. Count days between two dates, excluding weekends (MySQL only)

  2. How to count date difference excluding weekend and holidays in MySQL

  3. Calculate diffference between 2 dates in SQL, excluding weekend days

但没有得到最有希望的解决方案,因此我可以在我的 mysql 函数中使用它来查询数十万行。

这是一个非常新的概念,但不适用于像 @start_date = '2013-08-03' , @end_date = '2013-08-21' 这样的输入 预期答案:13 , 它只给出 12,

SELECT 5 * (DATEDIFF(@end_date, @start_date) DIV 7) + MID('0123444401233334012222340111123400012345001234550', 7 * WEEKDAY(@start_date) + WEEKDAY(@end_date) + 1, 1);

所以我确实尝试过自己制作 -

Concept : 
Input : 1. period_from_date  - from date
        2. period_to_date    - to date
        3. days_to_exclude   - mapping : S M T W TH F Sat   =>  2^0 + 2^6
          (sat and sun to exclude)       ^ ^ ^ ^ ^  ^  ^
                                         0 1 2 3 4  5  6

DELIMITER $$

USE `db_name`$$

DROP FUNCTION IF EXISTS `FUNC_CALC_TOTAL_WEEKDAYS`$$

CREATE DEFINER=`name`@`%` FUNCTION `FUNC_CALC_TOTAL_WEEKDAYS`( period_from_date DATE, period_to_date DATE, days_to_exclude INT ) RETURNS INT(11)
BEGIN

DECLARE period_total_num_days      INT DEFAULT 0;
DECLARE period_total_working_days  INT DEFAULT 0;
DECLARE period_extra_days          INT DEFAULT 0;
DECLARE period_complete_weeks      INT DEFAULT 0;
DECLARE extra_days_start_date      DATE DEFAULT '0000-00-00';
DECLARE num_days_to_exclude        INT DEFAULT 0;
DECLARE start_counter_frm          INT DEFAULT 0;
DECLARE end_counter_to             INT DEFAULT 6;
DECLARE temp_var                   INT DEFAULT 0;

# if no day to exclude return date-diff only
IF days_to_exclude = 0 THEN
    RETURN DATEDIFF( period_to_date, period_from_date ) + 1 ;
END IF;

# get total no of days to exclude
WHILE start_counter_frm <= end_counter_to  DO
   SET temp_var = POW(2,start_counter_frm) ;
   IF (temp_var  & days_to_exclude) = temp_var  THEN
            SET num_days_to_exclude = num_days_to_exclude + 1;
   END IF;
 SET start_counter_frm = start_counter_frm + 1;
END WHILE;

# Get period days count
SET period_total_num_days       = DATEDIFF( period_to_date, period_from_date ) + 1 ;
SET period_complete_weeks       = FLOOR( period_total_num_days /7 );
SET period_extra_days           = period_total_num_days  - ( period_complete_weeks * 7 );
SET period_total_working_days   = period_complete_weeks * (7 - num_days_to_exclude);
SET extra_days_start_date       = DATE_SUB(period_to_date,INTERVAL period_extra_days DAY);

# get total working days from the left days
WHILE period_extra_days > 0 DO
    SET temp_var = DAYOFWEEK(period_to_date) -1;

    IF POW(2,temp_var) & days_to_exclude != POW(2,temp_var) THEN
        SET period_total_working_days = period_total_working_days +1;
    END IF;

    SET period_to_date = DATE_SUB(period_to_date,INTERVAL 1 DAY);
    SET period_extra_days = period_extra_days -1;

END WHILE; 

RETURN period_total_working_days;
END$$

DELIMITER ;

请让我知道这会失败的漏洞。接受任何建议和评论。

最佳答案

更新:如果您只需要两个日期之间的工作日数,您可以这样获取

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

注意:如果您切换开始 date1 和结束 date2 日期,该功能仍然有效.

示例用法:

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

输出:

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

这是 DBFiddle 演示

关于mysql函数计算两个日期之间的天数,不包括周末,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52502143/

相关文章:

mysql - 替换表中的行

mysql - @MapsId 以及与 session 关联的具有相同标识符值的两个对象

mysql - 使用自动增量在 Mysql 数据库中设置 PK(string,int)

mysql - 如何使用 SQL 应用连接查询

php - 根据以下列出列中的所有日期

php - 如何订购数据两次。但是使第一个订单无效

mysql - Rails-MySQL 错误 - 未初始化的常量 MysqlCompat::MysqlRes

php - Laravel mysqldump 创建空文件,但通过 xampp shell 执行时相同的命令可以工作

Mysql:相同的查询,相同数量的结果行,没有连接,慢 10 倍?

php - 获取点击链接,在另一个页面显示产品