2012-03-17 103 views
0

我有2个表。一个包含项目列表,另一个包含这些项目中的任务列表。检索所有记录,其中所有相关记录等于字符串

我想拉一个只列出所有任务状态为“完成”的项目列表。

我的数据是这样的:

项目表:

ID,ProjectName,ProjectStatus 

任务表:

ID, ProjectID, TaskName, TaskStatus 

Tasks.ProjectID = Projects.ID

我可以做的基本的SELECT语句来获得所有记录,并且可以过滤TaskStatus处于特定状态的位置,但又是一次,我只想要一个完成所有任务的项目列表。

在此先感谢您的帮助!

+1

现在只是为了确保:当你说所有的相关任务后,您使用的传统方式术语,意思是其所有的零个或多个任务已完成,或通过一些机会你会要求项目至少有一项任务?通常情况下,一个没有相关任务的项目将是你想要的东西,但有些人却以有趣的非经典逻辑方式使用“全部”...... – 2012-03-17 23:43:52

+0

感谢您提出澄清。我的意思是全部。我创建了应用程序,以便在创建项目时创建一个初始任务。 – 2012-03-18 13:21:58

回答

1

您可以使用NOT EXISTS子查询:

select * 
    from Projects P 
where NOT EXISTS (select 1 from Tasks where Tasks.ProjectID = P.ID and TaskStatus <> 'COMPLETE') 

编辑完成

您还可以使用NOT IN子查询:

select * 
    from Projects 
where ID NOT IN (select ProjectID from Tasks where TaskStatus = 'COMPLETE') 

是否使用一个或另外,它将取决于你的表数据量和索引:

第一个选项将为父查询的每一行运行子查询,但将通过ProjectID索引访问(如果存在,可能是)。

第二个选项将首先运行子查询,仅运行一次,然后使用子查询结果运行父查询。但是子查询可能不会使用任何索引,因为它不可能在TaskStatus字段上有一个索引(这没有多大意义)。

但是,如果Tasks表中没有多行,那么在任何情况下都不会使用索引,因为只对表执行全面扫描会更便宜。因此,我的建议是,检查执行计划,比较成本,如果可能的话运行几个基准来决定这个选项或其他任何情况。

+0

谢谢。这正是我需要的。 – 2012-03-18 19:27:16

+0

酷!选择答案然后! :) – 2012-03-18 19:29:58

0

试试这个:

SELECT ID, ProjectName   -- This query will select all projects where 
FROM Projects      -- ID is not on the list of the subquery 
WHERE ID NOT IN          
     (SELECT ProjectID     -- This subquery will get all 
      FROM Tasks       -- ProjectID who has INCOMPLETE 
      WHERE TaskStatus <> 'COMPLETE')  -- taskStatus 
相关问题