I went through a problem like this once, we solved it like this:
Table of dias_uteis
:
CREATE TABLE dias_uteis(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
data_util DATE
);
I made a procedure
where I spend the year and she inserts for me all dates except sábado e domingo
:
--WARNING! ERRORS ENCOUNTERED DURING SQL PARSING!
DROP PROCEDURE
IF EXISTS sp_insere_datas_ano;
DELIMITER |
CREATE PROCEDURE sp_insere_datas_ano (p_ano INT)
BEGIN
DECLARE v_date DATE DEFAULT CONCAT (
p_ano
,'-01-01'
);
DECLARE v_qtd_dias INT DEFAULT 365;
DECLARE v_cont INT DEFAULT 1;
WHILE v_cont < v_qtd_dias DO
-- AQUI VOCÊ NÃO INSERE SABADOS E DOMINGOS
IF DAYOFWEEK(v_date) != 1
AND DAYOFWEEK(v_date) != 7 THEN
INSERT INTO dias_uteis (data_util) VALUE (v_date);
END
IF ;
SET v_date = DATE_ADD(v_date, INTERVAL + 1 DAY);
SET v_cont = v_cont + 1;END
WHILE ;END |
DELIMITER;
-- CALL sp_insere_datas_ano(2017);
We take the calendar of the year and remove the holidays:
DELETE
FROM dias_uteis
WHERE data_util = [data_deletar];
To count the working days only carry out the consultation:
SELECT count(*)
FROM dias_uteis
WHERE data_util BETWEEN [inicio]
AND [fim]
An extra case would be municipal holidays, which we could solve as follows:
CREATE TABLE municipios (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
,nome VARCHAR(100)
);
CREATE TABLE municipio_dia_ignorar (
id INT (11) NOT NULL AUTO_INCREMENT
,id_dia_util INT (11) DEFAULT NULL
,id_municipio INT (11) DEFAULT NULL
,PRIMARY KEY (id)
,KEY fk_municipio_dia_ignorar_dia_util(id_dia_util)
,KEY fk_municipio_dia_ignorar_municipio(id_municipio)
);
Let’s insert the city of Curitiba
INSERT INTO municipios (nome)
VALUES ('Curitiba');
Let us consider what day 07/09/2017
is a national holiday and that Curitiba has as municipal holiday day 08/09/2017
, we would delete day 7 from the day table
and insert day 8 into the skip table:
DELETE
FROM dias_uteis
WHERE data_util = '2017-09-07';
INSERT INTO municipio_dia_ignorar (
id_dia_util
,id_municipio
)
SELECT id
,1
FROM dias_uteis
WHERE dias_uteis.data_util = '2017-09-08';
We check the amount of working days from day 1 to day 10:
SELECT COUNT(*)
FROM dias_uteis d
LEFT JOIN municipio_dia_ignorar mi ON mi.id_dia_util = d.id
AND mi.id_municipio = 1
WHERE d.data_util BETWEEN '2017-09-01'
AND '2017-09-10'
AND mi.id IS NULL
And the return would be 4 days:
01/09
04/09
05/09
06/09
Working days only?
– UzumakiArtanis
@Stormwind ended up expressing me badly, but I updated the question, see if improved the explanation.
– celsomtrindade
You will need a table with the holidays you want to consider https://stackoverflow.com/questions/10330836/how-to-count-date-difference-excluding-weekend-and-holidays-in-mysql
– Pablo Tondolo de Vargas
To eliminate weekends (Saturday and Sunday), you can use the function
DAYOFWEEK
which returns the day of the week its date is. It would look like this:where DAYOFWEEK(data) not in (1,7)
. Now for business days it is necessary to have an auxiliary table that stores this information.– Marconi