Mysql
 sql >> Database >  >> RDS >> Mysql

Come si escludono i fine settimana da un date_sub?

Questa domanda riguarda la sottrazione dei giorni lavorativi. Supponendo che il fine settimana sia sabato-domenica, possiamo scrivere la soluzione come segue:

Sappiamo che:

  • Ogni settimana intera ha 5 giorni lavorativi.
  • Quindi,
    • numero_di_settimane =floor(@num_working_days / 5)
    • delta_giorni =@num_working_days % 5

Quindi, una prima approssimazione potrebbe essere:

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)

Tuttavia, questo non funzionerà nei seguenti casi e simili:

In genere, fallirà se:

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

Per tener conto di ciò, devono essere sottratti altri 2 giorni ogni volta che questa condizione viene soddisfatta.

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

Quindi, la seconda approssimazione sarebbe:

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,

Funzionerà finché now() non è in un week-end giorno. In tal caso, dovresti sostituire now() nella formula sopra con la data di fine settimana precedente:

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

Il che porta all'aspetto orribile ma perfettamente funzionante:

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

Ora, in fase di produzione, ti consiglio di creare una funzione sul tuo server MySQL per incapsulare questa logica e puoi chiamare questa funzione ogni volta che devi sottrarre giorni lavorativi.