This can be done directly, without a CTE or subquery:
This will return which Employees
have worked on a Project
with a John Smith1, but who are not a John Smith:
SELECT DISTINCT
Coworker.EmpNum
,Coworker.Fname
,Coworker.Lname
FROM
t1 Emp
INNER JOIN
t2 EmpProject
ON EmpProject.EmpNum = Emp.EmpNum
INNER JOIN
t2 CoworkerProject
ON CoworkerProject.ProjNum = EmpProject.ProjNum
INNER JOIN
t1 Coworker
ONAND CoworkerCoworkerProject.EmpNum =<> CoworkerProjectEmp.EmpNum
INNER JOIN
t1 Coworker
ANDON Coworker.EmpNum <>= EmpCoworkerProject.EmpNum
WHERE
Emp.Fname = 'John'
AND Emp.Lname = 'Smith'
To explain the logic of the query:
- Find all
EmpNum
whereFName = 'John'
andLname = 'Smith'
. - Find all all
ProjNum
whereEmpNum
matches results from 1. Because the primary key should be (ProjNum,EmpNum
) this will yield one row perProjNum
. - Find all
EmpNum
where theProjNum
matches those from 2 butEmpNum
is not equal to anyEmpNum
found in 1. - Retrieve
Fname
andLname
for allEmpNum
in 3. - Remove duplicates (same
Employee
could work on multiple projects with a John Smith).
1 Obviously there could be multiple John Smiths so it might be better to select a particular John Smith's EmpNum
directly before searching, but if you're not concerned with which John Smith the above will suffice.