Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak wykluczyć weekendy z date_sub?

To pytanie dotyczy odejmowania dni roboczych. Zakładając, że weekend to sobota-niedziela, rozwiązanie możemy napisać w następujący sposób:

Wiemy, że:

  • Każdy pełny tydzień ma 5 dni roboczych.
  • Zatem
    • num_of_weeks =floor(@num_working_days / 5)
    • delta_days =@num_working_days % 5

Zatem pierwszym przybliżeniem może być:

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)

Nie będzie to jednak działać w następujących i podobnych przypadkach:

Generalnie nie powiedzie się, jeśli:

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

Aby to uwzględnić, należy odjąć dodatkowe 2 dni za każdym razem, gdy ten warunek zostanie spełniony.

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

Tak więc drugie przybliżenie byłoby następujące:

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)

Wreszcie

Będzie to działać tak długo, jak now() nie jest w week-end dzień. W takim przypadku musisz zastąpić now() w powyższym wzorze z datą zakończenia poprzedniego tygodnia:

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

Co prowadzi do okropnego wyglądu, ale w pełni działającego:

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

Teraz, w środowisku produkcyjnym, zalecam utworzenie funkcji na serwerze MySQL, która hermetyzuje tę logikę, i można ją wywołać za każdym razem, gdy trzeba odjąć dni robocze.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Procedura zapisana z opcjonalnymi parametrami WHERE

  2. Wybierz najnowszy rekord w tabeli (pole datetime)

  3. Wstawianie do MySQL z PHP (jQuery/AJAX)

  4. Mysql, aby wybrać rekord miesięczny, nawet jeśli dane nie istnieją

  5. Jak mogę utworzyć ciągłą grupę w MySQL?