有一个非常简单的表结构:
CREATE TABLE dbo.employees (id int PRIMARY KEY);
CREATE TABLE dbo.assignments (id int PRIMARY KEY, employee_id int );
CREATE TABLE dbo.contracts (id int PRIMARY KEY, assignment_id int );
CREATE TABLE dbo.tasks (id int PRIMARY KEY, contract_id int );
员工 - <作业 - <合同 - <任务
我想选择所有没有相关任务的员工。
最有效的方法是什么?
答案 0 :(得分:2)
select id
from employees E
where not exists (
select *
from assignments A
join contracts C on A.ID = C.assignment_id
join tasks T on C.ID = T.contract_id
where A.employee_id = E.id)
答案 1 :(得分:2)
您可以inner join
前3个表格,并使用not in
作为第4个。
select
e.*
from dbo.employees e
inner join dbo.assignments a on a.employee_id = e.id
inner join dbo.contracts c on c.assignment_id = a.id
where c.id not in (select distinct contract_id from dbo.tasks)
答案 2 :(得分:0)
将EMPLOYEE_ID添加到TASK表。然后你可以检查COUNT(EMPLOYEE_ID)是否为零。
请注意,您定义这些实体的方式会强制您“走”从员工到合同的整个路径,再到分配到任务。将自然键添加到每个实体将使您能够直接转到所需的数据。您仍然可以保留标识列以提高索引效率。
自然关键建议: 合同(EMPLOYEE_ID,CONTRACT_ID); 转让(EMPLOYEE_ID,CONTRACT_ID,ASSIGNMENT_ID); 任务(EMPLOYEE_ID,CONTRACT_ID,ASSIGNMENT_ID,TASK_ID)。
请注意,这些都应该是可选的(1:M)关系。