sql >> Database >  >> RDS >> Mysql

Hoe sluit je weekenden uit van een date_sub?

Deze vraag gaat over het aftrekken van werkdagen. Ervan uitgaande dat het weekend zaterdag-zondag is, kunnen we de oplossing als volgt schrijven:

We weten dat:

  • Elke volledige week heeft 5 werkdagen.
  • Dus,
    • num_of_weeks =floor(@num_working_days / 5)
    • delta_days =@num_working_days % 5

Een eerste benadering zou dus kunnen zijn:

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)

Dit werkt echter niet in de volgende en vergelijkbare gevallen:

Over het algemeen zal het mislukken als:

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

Hiervoor moeten 2 extra dagen worden afgetrokken wanneer aan deze voorwaarde wordt voldaan.

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

Dus de tweede benadering zou zijn:

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)

Eindelijk,

Dit werkt zolang als now() is niet in een week-end dag. In dat geval moet u now() . vervangen in de bovenstaande formule met de vorige weekeinddatum:

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

Wat leidt tot het vreselijke maar volledig werkende:

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

Nu, in productie, raad ik aan dat je een functie op je MySQL-server maakt om deze logica in te kapselen, en je kunt deze functie aanroepen wanneer je werkdagen moet aftrekken.



  1. MySQL Atomic UPDATE in InnoDB versus MyISAM

  2. Hoe aliassen te gebruiken in wiskundige operatoren in SQL?

  3. Uniek identificerende foldermarkeringen

  4. Hoe mysql-waarschuwing op te lossen:InnoDB:page_cleaner:1000 ms bedoelde lus duurde XXX ms. Zijn de instellingen misschien niet optimaal?