Ms-Access

選擇未完成所有培訓的員工

  • August 26, 2022

我不是頻繁的 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:

SELECT firstname, lastname
FROM "Completed Training"
GROUP BY firstname, lastname
HAVING COUNT(DISTINCT "Training Code") < ( SELECT COUNT(1)
                                          FROM Training );

這個想法是計算每個員工的不同培訓程式碼的數量,並將其與可用培訓程式碼的數量進行比較。

這在大多數情況下都可以正常工作,但是,根本不會報告未接受任何培訓的員工。另一種選擇(簡化設置):

select name
from employees e
where exists (
   select 1 from training t
   where not exists (
        select 1 from completed_training ct
        where ct.name = e.name
        and ct.training_code = t.training_code
   )
);

後者的想法是檢查是否存在員工沒有接受過培訓的培訓。

我已經為 postgres 添加了一個Fiddle,其中包含這些查​​詢和第三個查詢,該查詢從員工和培訓之間的笛卡爾積中減去了 completed_trainings。

引用自:https://dba.stackexchange.com/questions/316079