2013-04-18 182 views
2

table A, B and CSQL - 相关子查询

我要回表A中不表B和该列表中存在的所有条目表不存在C.

select * from table_A as a 
where not exists (select 1 from table_B as b 
where a.id = b.id) 
的多层

这让我在一个不在B.条目的第一个结果但现在我想只有那些还没有C.

我试过的口味的这个结果的条目:

select * from table_A as a 
where not exists (select 1 from table_B as b 
where a.id = b.id) 
AND 
where not exists (select 1 from table_C as c 
where a.id = c.id) 

但这不是正确的逻辑。如果有一种方法可以存储来自第一个查询的结果,然后从表C中不存在的结果中选择*,但我不确定该怎么做。我很感激帮助。

+1

你使用什么数据库系统演示? –

+0

我正在使用MS sql – codingknob

回答

2

在第二个查询的(外部部分)中有两个WHERE子句。这不是有效的SQL。如果你删除它,它应该按预期工作:

select * from table_A as a 
where not exists (select 1 from table_B as b 
        where a.id = b.id) 
AND 
     not exists (select 1 from table_C as c   -- WHERE removed 
        where a.id = c.id) ; 

测试中SQL-Fiddle(日Thnx @Alexander)

2

怎么样使用LEFT JOIN

SELECT a.* 
FROM TableA a 
     LEFT JOIN TableB b 
      ON a.ID = b.ID 
     LEFT JOIN TableC c 
      ON a.ID = c.ID 
WHERE b.ID IS NULL AND 
     c.ID IS NULL 
3

试试这个:

select * from (
    select a.*, b.id as b_id, c.id as c_id 
    from table_A as a 
    left outer join table_B as b on a.id = b.id 
    left outer join table_C as c on c.id = a.id 
) T 
where b_id is null 
    and c_id is null 

另一种实现是这样的:

select a1.* 
from table_A as a1 
inner join (
    select a.id from table_A 
    except 
    select b.id from table_B 
    except 
    select c.id from table_c 
) as a2 on a1.id = a2.id 

请注意如here所述的子查询形式的限制。第二个实现,通过最简洁明确地描述SQL Server所需的操作,可能是最有效的。

1

我不喜欢“不存在”,但如果由于某种原因,它似乎更符合你的逻辑;那么你可以为你的第一个查询使用别名。随后,您可以重新应用另一个“不存在”子句。例如:

SELECT * FROM 
    (select * from tableA as a 
    where not exists (select 1 from tableB as b 
    where a.id = b.id)) 
AS A_NOT_IN_B 
WHERE NOT EXISTS (
    SELECT 1 FROM tableC as c 
    WHERE c.id = A_NOT_IN_B.id 
) 
2

有没有一个更选项存在于SQLFiddle

操作

SELECT * 
FROM dbo.test71 a 
WHERE NOT EXISTS(
       SELECT 1 
       FROM (SELECT b.ID 
         FROM dbo.test72 b 
         UNION ALL 
         SELECT c.ID 
         FROM dbo.test73 c) x 
       WHERE a.ID = x.ID 
       ) 

演示

从@ ypercube的选项。谢谢你目前;)

SELECT * 
FROM dbo.test71 a 
WHERE NOT EXISTS(
       SELECT 1 
       FROM dbo.test72 b 
       WHERE a.ID = b.ID 
       UNION ALL 
       SELECT 1 
       FROM dbo.test73 c 
       WHERE a.ID = c.ID 
       ); 

SQLFiddle

+1

不错。您也可以在答案中添加此变体:[SQL-Fiddle](http://sqlfiddle.com/#!3/b10f3/3) –