Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como você exclui fins de semana de um date_sub?


Esta pergunta é sobre a subtração de dias úteis. Assumindo que o fim de semana é sábado-domingo, podemos escrever a solução da seguinte forma:

Sabemos que:
  • Toda semana inteira tem 5 dias úteis.
  • Assim,
    • num_of_weeks =floor(@num_working_days / 5)
    • delta_days =@num_working_days % 5

Assim, uma primeira aproximação poderia ser:
SET @num_working_days = 4; -- pick any integer
SET @num_days = 7 * FLOOR(@num_working_days / 5) - @num_working_days % 5;     
SELECT DATE_SUB(NOW(), INTERVAL @num_days DAY)

No entanto, isso não funcionará nos seguintes casos e em casos semelhantes:

Geralmente, ele falhará se:
WEEKDAY(NOW()) - @num_working_days % 5 < 0

Para compensar isso, um adicional de 2 dias deve ser subtraído sempre que essa condição for atendida.
  • overflow_days =2 * (WEEKDAY(NOW()) - @num_working_days % 5 < 0)

Então, a segunda aproximação seria:
SET @num_working_days = 4;
SET @overflow_days = 2 * (WEEKDAY(NOW()) - @num_working_days % 5 < 0)
SET @num_days = 7 * FLOOR(@num_working_days / 5) - @num_working_days % 5;

SELECT DATE_SUB(NOW(), INTERVAL @num_days DAY)

Finalmente,


Isso funcionará enquanto now() não está em um week-end dia. Nesse caso, você precisaria substituir now() na fórmula acima com a data de término da semana anterior:
  • weekend_correction =DATE_SUB(NOW(), INTERVAL WEEKDAY(NOW()) % 5 DAY)

O que leva à aparência horrível, mas totalmente funcional:
SET @num_working_days = 4;
SET @weekend_correction = DATE_SUB(NOW(), INTERVAL WEEKDAY(NOW()) % 5 DAY);
SET @overflow_days = 2 * (WEEKDAY(@weekend_correction) - @num_working_days % 5 < 0);
SET @num_days = 7 * FLOOR(@num_working_days / 5) - @num_working_days % 5;

SELECT DATE_SUB(@weekend_correction, INTERVAL @num_days DAY); 

Agora, em produção, recomendo que você crie uma função em seu servidor MySQL para encapsular essa lógica, e você pode chamar essa função sempre que precisar subtrair dias úteis.