programing

두 날짜 범위 내에서 날짜를 얻는 방법은 무엇입니까?

megabox 2023. 7. 8. 10:48
반응형

두 날짜 범위 내에서 날짜를 얻는 방법은 무엇입니까?

2021년 12월의 모든 날짜가 포함된 달력 표를 가지고 있습니다(표 내에서 일부 날짜만 예로 들지만 실제로는 해당 달의 모든 날짜가 포함되어 있는 것으로 이해됨).

아이디 날짜.
01 2021-12-01
02 2021-12-02
03 2021-12-03
04 2021-12-04
05 2021-12-05

사용자 테이블이 있습니다.

아이디 이름. num_html
01 앤드루 101
02 메리 102

테이블 어시스턴스가 있습니다.

아이디 날짜. num_html
01 2021-12-03 101
02 2021-12-04 101
03 2021-12-03 102
04 2021-12-04 102
05 2021-12-05 101
06 2021-12-06 102

직원 번호, 이름, 참석한 날짜 및 결석한 날짜를 표시하기 위해 질문이 있습니다.

SELECT u.num_employee,
       u.name,
       a.date AS attendances,
        (SELECT GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM calendar
           WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
           AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),a.date)) as faults FROM users u
JOIN (SELECT num_employee,
      GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM attendances
      WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
      GROUP BY num_employee) a ON a.num_employee = u.num_employee

위의 질문을 통해 다음과 같은 정보를 얻을 수 있습니다.

num_html 이름. 출석률 결점
101 앤드루 3,4,5 1,2,3,6,7,8,9,10...
102 메리 3,4,6 1,2,5,7,8,9,10...

자, 요점은 출석표 외에 휴가라는 또 다른 표를 고려해야 한다는 것입니다.이 표의 구조는 다음과 같습니다.

이드 이니셜_날짜 최종 날짜 num_html
01 2021-12-07 2021-12-09 101
02 2021-12-07 2021-12-09 102

그리고 이 표를 고려할 때 휴가로 처리되는 범위 내의 날짜는 "결함" 열에 표시되는 것을 중지해야 합니다.결과는 다음과 같습니다.

num_html 이름. 출석률 결점
101 앤드루 3,4,5 1,2,3,6,10...
102 메리 3,4,6 1,2,5,10...

위의 내용을 얻으려면 쿼리를 어떻게 조정해야 합니까?

문제의 쿼리는 제가 사용하고 있는 MariaDB 버전을 고려할 때 CTE를 사용하도록 조정할 수 없습니다.저는 phpMyAdmin에서 일하고 있습니다.

MySQL 및 MariaDB는 시퀀스가 좋지 않으므로 실행할 캘린더 테이블이 있는 것이 좋습니다.

그래서 휴가 날짜를 검색하는 또 다른 하위 질의가 필요합니다.

제가 사용한 것입니다.GROUP BY한 달에 1개 이상의 휴가 기간이 있을 수 있기 때문에 하위 선택 항목에 있습니다.

SELECT u.num_employee,
       u.name,
       a.date AS attendances,
        (SELECT GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM calendar
           WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
           AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),a.date)
           AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),vac.vac_days)) as faults 
FROM users u
LEFT JOIN  (SELECT num_employee,
      GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM attendances
      WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
      GROUP BY num_employee) a ON a.num_employee = u.num_employee
LEFT JOIN (SELECT v.`num_employee`, GROUP_CONCAT(DAY(c.`date`)) vac_days
FROM vacations v INNER JOIN calendar c ON c.`date` BETWEEN v.`initial_date` AND `final_date`
AND c. date BETWEEN '2021-12-01' AND '2021-12-31'
GROUP BY v.`num_employee`) vac ON vac.`num_employee` = u.num_employee
num_https | 이름 | 출석 | 과실-----------: | :----- | :---------- | :----------101 | 앤드류 | 3,4,5 | 1,2,6,10,11102 | 메리 | 3,4,6 | 1,2,5,10,11

db<>여기로 이동

FIND_IN_SET에는 문자열이 필요하지만 사용할 수 없습니다.NULL따라서 NULL 값을 확인하고 교체해야 합니다.

SELECT u.num_employee,
       u.name,
       a.date AS attendances,
        (SELECT GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM calendar
           WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
           AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),IFNULL(a.date,''))
           AND NOT FIND_IN_SET(EXTRACT(DAY FROM date),IFNULL(vac.vac_days,''))
           ) as faults 
FROM users u
LEFT JOIN  (SELECT num_employee,
      GROUP_CONCAT(DISTINCT EXTRACT(DAY FROM date)) AS date FROM attendances
      WHERE date BETWEEN '2021-12-01' AND '2021-12-31'
      GROUP BY num_employee) a ON a.num_employee = u.num_employee
LEFT JOIN (SELECT v.`num_employee`, GROUP_CONCAT(DAY(c.`date`)) vac_days
FROM vacations v INNER JOIN calendar c ON c.`date` BETWEEN v.`initial_date` AND `final_date`
AND c. date BETWEEN '2021-12-01' AND '2021-12-31'
GROUP BY v.`num_employee`) vac ON vac.`num_employee` = u.num_employee
num_https | 이름 | 출석 | 과실-----------: | :----- | :---------- | :----------------101 | 앤드류 | 3,4,5 | 1,2,6,10,11102 | 메리 | 3,4,6 | 1,2,5,7,8,9,10,11

db<>여기로 이동

언급URL : https://stackoverflow.com/questions/71269384/how-to-get-the-days-within-a-range-of-two-dates

반응형