选择没有嵌套关联记录的行

时间:2014-04-02 13:52:59

标签: sql sql-server

有一个非常简单的表结构:

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 );

员工 - <作业 - <合同 - <任务

我想选择所有没有相关任务的员工。

最有效的方法是什么?

3 个答案:

答案 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)关系。