我不是频繁的 DBA,但我正在做一些事情来跟踪一些员工的培训完成情况,但我有点卡住了。我正在使用 MICROSOFT ACCESS 并有 3 个表:
Employees
Last_Name (PK) | First_Name (PK)
----------+-----------
Smith | Bob
Bee | Susy
...
Training
Training_Code (PK) | Description
--------------+-----------
001.001 | Orientation
001.002 | Fundamentals of Stuff
...
Completed Training (many-to-many)
Last_Name (FK)| First_Name (FK) | Training Code (FK) | Completion Date
----------+-----------------+--------------------+-----------
Smith | Bob | 001.001 | 8/25/2022
Smith | Bob | 001.002 | 8/25/2022
Bee | Susy | 001.001 | 8/25/2022
Bee | Susy | 001.002 | 8/25/2022
...
我的目标是简单地编写一个查询,返回所有未完成所有培训的员工。为此,我的计划是查询Employees
表,然后执行子查询来计算表中给定员工的所有条目Completed_Training
。最后,我会计算表中的总行数Training
。如果员工完成了所有可用的培训,那么这两个数字将匹配并且查询不应在结果中返回他们的姓名。我最好的尝试是这样的:
SELECT *
FROM Employees
WHERE (COUNT(SELECT * FROM Completed_Training WHERE Completed_Training.Last_Name = Employees.Last_Name)) < (COUNT(SELECT * FROM Training));
我得到了错误,Cannot have aggregate function in WHERE clause (COUNT()<).
但是,我显然没有正确地概念化这一点。谁能指出我正确的方向?
不知道它是否适用于 ms-access:
这个想法是计算每个员工的不同培训代码的数量,并将其与可用培训代码的数量进行比较。
这在大多数情况下都可以正常工作,但是,根本不会报告未接受任何培训的员工。另一种选择(简化设置):
后者的想法是检查是否存在员工没有接受过培训的培训。
我已经为 postgres 添加了一个Fiddle,其中包含这些查询和第三个查询,该查询从员工和培训之间的笛卡尔积中减去了 completed_trainings。