Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment exclure les week-ends d'un date_sub ?

Cette question porte sur la soustraction de jours ouvrables. En supposant que le week-end est du samedi au dimanche, nous pouvons écrire la solution comme suit :

Nous savons que :

  • Chaque semaine complète compte 5 jours ouvrés.
  • Ainsi,
    • num_of_weeks =floor(@num_working_days / 5)
    • delta_days =@num_working_days % 5

Ainsi, une première approximation pourrait être :

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)

Cependant, cela ne fonctionnera pas dans les cas suivants et similaires :

Généralement, cela échouera si :

WEEKDAY(NOW()) - @num_working_days % 5 < 0

Pour tenir compte de cela, 2 jours supplémentaires doivent être soustraits chaque fois que cette condition est remplie.

  • overflow_days =2 * (WEEKDAY(NOW()) - @num_working_days % 5 < 0)

Ainsi, la seconde approximation serait :

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)

Enfin,

Cela fonctionnera tant que now() n'est pas dans un week-end journée. Dans ce cas, vous devrez remplacer now() dans la formule ci-dessus avec la date de fin de semaine précédente :

  • weekend_correction =DATE_SUB(NOW(), INTERVAL WEEKDAY(NOW()) % 5 DAY)

Ce qui conduit à l'apparence horrible mais qui fonctionne parfaitement :

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

Maintenant, en production, je vous recommande de créer une fonction sur votre serveur MySQL pour encapsuler cette logique, et vous pouvez appeler cette fonction chaque fois que vous avez besoin de soustraire des jours ouvrables.