计算两个date之间的天数,不包括周末(仅限MySQL)
我需要计算MySQL中两个date(周六和周日)之间的差异(以天为单位)。 也就是说,天数之差减去周六和周日之间的数量。
目前,我只用数字来计算这些日子:
SELECT DATEDIFF('2012-03-18', '2012-03-01')
这个回报17
,但我想排除周末,所以我想12
(因为第三,第四,第十,第十一和第十七是周末天)。
我不知道从哪里开始。 我知道WEEKDAY()
函数和所有相关的,但我不知道如何在这种情况下使用它们。
插图:
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
只需使用一个简单的函数来尝试它:
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);
testing:
SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1, TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2;
结果:
| WEEKDAYS1 | WEEKDAYS2 | ------------------------- | 13 | 13 |
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
IT对我有帮助
下面的逻辑只显示了多less天
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` )
您也可以使用查询来完成此操作,但是您需要一个涵盖date范围的date表。 无论如何,创build一个用于所有项目的date表是一个很好的习惯。
要创builddate表,您所做的只是生成一长串date(EXCEL是方便的方法,但还有其他方法)并将它们导入到表中。 然后,将这些date与各种date函数结合使用来导出“星期几”,“月”,“年”等,并将所有这些date保存到表中,如下所示:
tbl_dates
道琼斯工业平均指数是我的表中的“星期几”。 然后你的查询看起来像这样:
SELECT Count(theDate) AS numWeekDays FROM tbl_dates WHERE theDate >[startDate] And theDate <=[endDate] AND dow <> 1 AND dow <> 7;
在这种情况下,1和7分别是星期天和星期六(这是默认值),当然,如果需要为许多startDate(s)和endDate(s)计算此值,可以将其嵌套到另一个查询中。