programing

결근 날짜와 함께 직원의 이름을 표시하는 방법은 무엇입니까?

bestprogram 2023. 8. 5. 10:44

결근 날짜와 함께 직원의 이름을 표시하는 방법은 무엇입니까?

저는 직원이라는 테이블을 가지고 있습니다.

num_html 이름.
001 조지
002 메리

그리고 레코드라는 표는 다음과 같습니다.

num_html 날짜.
001 2021-12-01
002 2021-12-01
001 2021-12-02
002 2021-12-01
001 2021-12-03
002 2021-12-06

위의 예에서는 두 직원이 12월 1일과 2일에 모두 참석했습니다. Mary는 3일째에 결석했고 George는 6일째에 결석했습니다.4일과 5일은 주말이었기 때문에 비근무일(근무일은 월요일부터 금요일까지)이므로 결근으로 간주되지 않습니다.

제가 찾고 있는 것은 직원 번호, 이름, 결석한 날짜가 표시된 결과를 얻는 것입니다.

num_html 이름. 실종된
001 조지 2021-12-03
002 메리 2021-12-06

현재 제가 달성한 유일한 것은 다음과 같은 질문과 함께 직원 한 명의 결근을 표시하는 것입니다.

SELECT GROUP_CONCAT(date) as missing FROM
(SELECT ADDDATE('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) date FROM
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4) v
WHERE date BETWEEN '2021-12-01' AND '2021-12-31' AND date NOT IN (SELECT DATE_FORMAT(date,'%Y-%m-%d') FROM records WHERE num_employee = 001 AND date BETWEEN '2021 -12-01' AND '2022-12-31') AND DAYOFWEEK(date) BETWEEN 2 AND 5

이를 통해 모든 날짜가 포함된 테이블을 생성하고 날짜 범위와 직원 번호(이 경우 직원 001)를 지정하면 다음과 같은 결과를 얻을 수 있습니다.

실종된
2021-12-06

직원별 필터링 요구를 중지하고 직원이 부재 중일 때 모든 직원을 해당 날짜와 함께 표시하도록 쿼리를 조정하려면 어떻게 해야 합니까?

저는 phpMyAdmin에서 MariaDB와 함께 일하고 있습니다.

제가 당신의 질문을 올바르게 이해했다면, 이것은 효과가 있을 것입니다.

이렇게 하면 결합된 모든 데이터가 제공됩니다.

select e.num_employee, e.name, r.date
from employees e
join records r on r.num_employee = e.num_employee

이것은 마지막 실종자와 함께 직원별로 구분됩니다.

select e.num_employee, max(r.date) as last_missing
from employees e
join records r on r.num_employee = e.num_employee
group by employees.num_employee
SELECT e.num_employee, e.name, max(r.date) AS missing

FROM records AS r

JOIN employees AS e ON e.num_employee = r.num_employee

GROUP BY e.num_employee

ORDER BY e.num_employee ASC

날짜 테이블이 있다고 가정하면 다음 작업을 수행할 수 있습니다.

select
    d.date
  , e.num_employee
  , e.name
from employees e
cross join date d
where 1=1
  and d.is_weekend = 0
  and d.date >= '2022-01-01'

이렇게 하면 가능한 모든 이름과 날짜 조합이 제공됩니다.대부분의 날짜 테이블은 1900년 또는 1990년까지 날짜를 유지하기 때문에 필터링합니다.대부분의 경우 1년에 한 번씩 그렇게 하고 싶어할 것입니다.네, 크로스 조인이 최선은 아니지만, 그 몇 개의 기록으로 문제가 되지 않을 것입니다.

사람이 누락된 날짜, 즉 항목이 없는 날짜만 원하는 경우 이를 필터링하려고 합니다.

select
    sub.num_employee
  , sub.name
  , sub.date as missing
from (
  select
      d.date
    , e.num_employee
    , e.name
  from employees e
  cross join date d
  where 1=1
    and d.is_weekend = 0
    and d.date >= '2022-01-01'
) sub
where not exists (
  select
    1
  from records r
  where 1=1
    and r.num_employee = sub.num_employee
    and r.date = sub.date
)

기록표에 결근이 아닌 직원의 참석이 포함되어 있고, 근무일마다 최소 한 명의 직원이 항상 참석한다고 가정하면 다음과 같은 효과가 있을 것입니다.

select v.num_employee, v.name, v.date as missing
from (select * from (select distinct `date` from records) u cross join employees) v left join records
on v.`date` = records.`date`
and v.num_employee = records.num_employee
where records.`date` is null;

피들

기본적으로, 최소한 한 명의 직원이 참석했던 모든 고유한 날짜를 기록 테이블에서 얻고, 모든 직원과 모든 근무일을 일치시키기 위해 직원 테이블과 교차 결합한 다음, 외부에서 결과를 기록 테이블과 결합하여 결근 여부를 확인합니다.

언급URL : https://stackoverflow.com/questions/71155239/how-to-display-the-name-of-the-employees-along-with-the-date-they-were-absent