phpmyadmin 如何显示员工的姓名沿着缺勤日期?

htrmnn0y  于 2022-11-09  发布在  PHP
关注(0)|答案(4)|浏览(144)

我公司有以下表名为× ×员工× ×:
| 雇员人数|姓名|
| - -|- -|
| 第001章|乔治|
| 002年|玛丽|
并将该表称为记录
| 雇员人数|日期|
| - -|- -|
| 第001章|2021年12月1日|
| 002年|2021年12月1日|
| 第001章|2021年12月2日|
| 002年|2021年12月1日|
| 第001章|2021年12月3日|
| 002年|2021年12月6日|
在上面的示例中,两名员工都在12月1日和2日参加了培训;玛丽在第3天缺勤,乔治在第6天缺勤。第4天和第5天是周末,因此不将其视为缺勤,因为这两天是非工作日(工作日为周一至周五)。
我希望得到一个显示员工编号、姓名和缺勤日期的结果:
| 雇员人数|姓名|缺失的|
| - -|- -|- -|
| 第001章|乔治|2021年12月3日|
| 002年|玛丽|2021年12月6日|
目前,我所完成的唯一工作是使用以下查询显示单个员工的缺勤情况:

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月6日|
如何修改查询以停止要求按员工筛选,并显示所有员工及其缺勤日期?
我在phpMyAdmin中使用MariaDB。

xu3bshqb

xu3bshqb1#

如果我没理解错你的问题,这就可以了。
这将为您提供所有连接的数据。

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
vohkndzv

vohkndzv2#

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
qgzx9mmu

qgzx9mmu3#

假设您有一个日期表(应该有),您可以执行以下操作:

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年的日期。大多数情况下,你会希望每年这样做。是的,交叉连接不是最好的,但有了这几个记录,它不会是一个问题。
现在,您需要过滤此内容,因为您只需要人员失踪的日期,即不存在条目的日期。

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

xpszyzbs4#

假设记录表包含雇员在场而不包含缺勤,并且假设每个工作日始终至少有一个雇员在场,则应该可以这样做:

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;

Fiddle
基本上,您可以获得至少有一个雇员在场的所有不同日期(从记录表中),将其与雇员表交叉连接以获得每个雇员和每个工作日之间的匹配,然后将结果与记录表进行外连接以检查缺勤情况。

相关问题