我需要计算MySQL中两个日期之间的差异(以天为单位),不包括周末(周六和周日)。也就是说,天数的差异减去周六和周日的数量。
目前,我只使用以下方式计算日期:
SELECT DATEDIFF('2012-03-18', '2012-03-01')
返回17
,但我想排除周末,所以我想12
(因为第3和第4,第10和第11和第17是周末的日子)。
我不知道从哪里开始。我知道WEEKDAY()
函数和所有相关函数,但我不知道如何在这种情况下使用它们。
答案 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 强>
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)计算它,你可以将它嵌套到另一个查询中。 )。