2

我有table A, B and C

我想返回表 A 中不存在于表 B 中且该列表中的所有条目在表 C 中不存在。

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

这给了我 A 中不在 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 中不存在的结果中选择 *。但我不知道该怎么做。我很感激帮助。

4

5 回答 5

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

请注意此处描述的对子查询形式的限制。第二种实现,通过最简洁和清晰地描述 SQL Server 所需的操作,可能是最有效的。

于 2013-04-18T01:53:37.933 回答
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)

于 2013-04-18T15:06:19.703 回答
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
于 2013-04-18T01:51:33.893 回答
2

NOT EXISTS 运算符的另一种选择

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
                 )  

SQLFiddle上的演示

来自@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上的演示

于 2013-04-18T20:40:23.897 回答
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
)
于 2013-04-18T03:21:27.063 回答