Cuente días entre dos fechas, excluyendo los fines de semana (solo MySQL)

Necesito calcular la diferencia (en días) entre dos fechas en MySQL excluyendo los fines de semana (sábado y domingo). Es decir, la diferencia en días menos el número de sábado y domingo en el medio.

Por el momento, simplemente cuento los días usando:

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

Este retorno 17 , pero quiero excluir los fines de semana, entonces quiero 12 (porque el 3 ° y 4 °, 10 ° y 11 ° y el 17 ° son fines de semana).

No sé por donde comenzar. Conozco la función WEEKDAY() y todas las relacionadas, pero no sé cómo usarlas en este contexto.

Ilustración:

 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 ) 

Pseudocódigo:

 @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 

Simplemente pruébalo usando una función simple:

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

Prueba :

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

Resultado:

 | 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 

Te puedo ayudar

La lógica de abajo solo muestra cuántos días como

 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; 

Consulta basada en tablas

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

También puede hacer esto con las consultas, pero necesitará una tabla de fechas que cubra los intervalos de fechas. Es una buena práctica crear tablas de fechas para usar en todos sus proyectos, de todos modos.

Para crear la tabla de fechas, todo lo que hace es generar una larga lista de fechas (EXCEL es un método conveniente, pero hay otras formas) e importarlas a una tabla. Luego, use esas fechas junto con varias funciones de fecha para derivar el ‘día de la semana’, ‘mes’, ‘año’, etc., y guarde todo eso en la tabla con las fechas, de esta manera:

tbl_dates

tabla de fechas

dow es ‘día de la semana’ en mi mesa. Entonces su consulta se ve así:

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

En este caso, 1 y 7 son domingo, sábado, respectivamente (que es el valor predeterminado) y, por supuesto, puede anidar eso en otra consulta si necesita calcular esto para muchos StartDate (s) y endDate (s).

Intereting Posts