Não sou um DBA frequente, mas estou trabalhando em algo para acompanhar o treinamento completo de alguns funcionários e estou um pouco travado. Estou usando o MICROSOFT ACCESS e tenho 3 tabelas:
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
...
Meu objetivo é simplesmente escrever uma consulta que retorne todos os funcionários que NÃO concluíram todo o treinamento. Para fazer isso, meu plano era consultar a Employees
tabela e depois fazer subconsultas para contar todas as entradas de um determinado funcionário na Completed_Training
tabela. Finalmente, eu contaria o número total de linhas na Training
tabela. Se um funcionário tiver concluído todo o treinamento disponível, os dois números serão correspondentes e a consulta NÃO DEVE retornar seu nome no resultado. Minha melhor tentativa é algo assim:
SELECT *
FROM Employees
WHERE (COUNT(SELECT * FROM Completed_Training WHERE Completed_Training.Last_Name = Employees.Last_Name)) < (COUNT(SELECT * FROM Training));
Eu recebo o erro, no Cannot have aggregate function in WHERE clause (COUNT()<).
entanto, claramente não estou conceituando isso direito. Alguém pode me apontar na direção certa?
Não faço ideia se funciona no ms-access:
A ideia é contar o número de códigos de treinamento distintos para cada funcionário e compará-lo com o número de códigos de treinamento disponíveis.
Isso funcionará bem para a maioria das situações, no entanto, os funcionários que não fizeram nenhum treinamento não serão relatados. Uma alternativa (configuração simplificada):
A ideia neste último é verificar se existe um treinamento tal que o funcionário não tenha treinado nele.
Eu adicionei um Fiddle para postgres com essas duas consultas e uma terceira consulta que subtrai completed_trainings do produto cartesiano entre funcionários e treinamentos.