programing

두 날짜 사이의 근무일만 계산하는 방법은 무엇입니까?

javamemo 2023. 6. 19. 21:04
반응형

두 날짜 사이의 근무일만 계산하는 방법은 무엇입니까?

휴가라는 표에는 직원 번호와 휴가 시작 및 종료 날짜가 표시되어 있습니다.

id_interval 시작 끝.
1001 2020-12-24 2021-01-04

제가 찾고 있는 것은 각 직원의 휴가 일수를 시각화하는 것이지만, 영업일이 아닌 날(토요일, 일요일, 공휴일)은 고려하지 않고 직원 수, 월, 연도 및 일 수로 구분하는 것입니다.

다음과 같은 질문이 있습니다. 토요일과 일요일을 게시물에서 제외할 수 있습니다.

SELECT id_employee, 
       EXTRACT(YEAR FROM t.Date) AS year, 
       EXTRACT(MONTH FROM t.Date) AS month, 
       SUM(WEEKDAY(`Date`) < 5) AS days 
FROM (SELECT v.id_employee, 
             DATE_ADD(v.start, interval s.seq - 1 DAY) AS Date 
FROM vacations v CROSS JOIN seq_1_to_100 s 
WHERE DATE_ADD(v.start, interval s.seq - 1 DAY) <= v.end 
ORDER BY v.id_employee, v.start, s.seq ) t 
GROUP BY id_employee, EXTRACT(YEAR_MONTH FROM t.Date);

제가 묻고 싶은 것은, 주말을 빼먹는 것 외에 휴일도 빼먹는 것이 어떻게 가능한가 하는 것입니다.해당 공휴일의 날짜가 저장된 다른 테이블을 설정해야 한다고 생각합니다. 하지만 제 *질문 *이 비교를 수행하기 위해 어떻게 조정될 수 있을까요?

직원 10012020-12-24부터 2021-01-04까지 휴가를 내고 크리스마스와 새해를 휴일로 받아들인다면 다음과 같은 결과를 얻을 수 있을 것입니다.

id_interval 연도 날들
1001 12 2020 5
1001 1 2021 1

휴일 날짜를 저장하는 테이블을 만든 후에는 다음과 같은 작업을 수행할 수 있습니다.

SELECT id_employee, 
       EXTRACT(YEAR FROM t.Date) AS year, 
       EXTRACT(MONTH FROM t.Date) AS month, 
       SUM(CASE WHEN h.holiday_date IS NULL THEN WEEKDAY(`Date`) < 5 END) AS days 
FROM (SELECT v.id_employee, 
             DATE_ADD(v.start, interval s.seq - 1 DAY) AS Date 
FROM vacations v CROSS JOIN seq_1_to_100 s 
WHERE DATE_ADD(v.start, interval s.seq - 1 DAY) <= v.end 
ORDER BY v.id_employee, v.start, s.seq ) t 
LEFT JOIN holidays h ON t.date=h.holiday_date
GROUP BY id_employee, EXTRACT(YEAR_MONTH FROM t.Date);

이 경우를 가정하면holidays테이블 구조는 다음과 같습니다.

CREATE TABLE holidays (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
holiday_date DATE,
holiday_description VARCHAR(255));

그리고나서LEFT JOIN현재 쿼리로 변경합니다.SUM()을 추가하여 약간CASE확인할 식을 입력합니다.만약에ON t.date=h.holiday_date왼쪽 조인 경기에서는 필드의 결과가 있습니다.h.holiday_date그렇지 않으면 그렇게 될 것입니다.NULL따라서 오직CASE h.holiday_date WHEN IS NULL ..고려될 것입니다.

데모 피들

공통 테이블 식을 지원하는 MariaDB 및 MySQL 버전과 호환되는 이 솔루션 추가:

WITH RECURSIVE cte AS
(SELECT id_employee, start, start lvdt, end FROM vacations 
    UNION ALL
 SELECT id_employee, start, lvdt+INTERVAL 1 DAY, end FROM cte 
   WHERE lvdt+INTERVAL 1 DAY <=end)

SELECT  id_employee,
        YEAR(v.lvdt) AS year, 
        MONTH(v.lvdt) AS month,
        SUM(CASE WHEN h.holiday_date IS NULL THEN WEEKDAY(v.lvdt) < 5 END) AS days
  FROM cte v 
  LEFT JOIN holidays h
     ON v.lvdt=h.holiday_date
  GROUP BY id_employee,
        YEAR(v.lvdt), 
        MONTH(v.lvdt);

언급URL : https://stackoverflow.com/questions/69815125/how-to-count-only-the-working-days-between-two-dates

반응형