查找表中不在SQL Server的其他表中的人数

时间:2017-05-23 16:25:35

标签: sql sql-server sql-server-2012

我有3个表(比方说A,B和C),我在所有3个表中都有一个公共密钥列,称为G. 我需要一个脚本来查找不在B或C(2级表)中的A(主表 - 1级)中的G的数量。基本上,我想在其他2个表的完全连接结果上加入一个表。

我尝试了左连接,但结果不正确。我使用了以下脚本:

SELECT COUNT(DISTINCT A.G)
FROM A LEFT JOIN B ON A.G = B.G
     FULL JOIN C ON A.G = C.G
WHERE (B.G IS NULL) OR (C.G IS NULL)

感谢您的帮助。

P.S。 正确答案的选择基于处理时间的优越性。我在我的数据集上运行了两种选择(存在与左连接)(相对较大且耗时)。

LEFT JOIN方法(选定答案)比EXISTS更具流程效率。前一个方法需要0:23分钟,而后一个方法需要7:52分钟。

4 个答案:

答案 0 :(得分:1)

使用not exists()count()行,GB中不存在C

select count(*)
from A
where not exists (select 1 from B where A.G = B.G)
   or not exists (select 1 from C where A.G = C.G)

如果您想count()GB中不存在C的行,请将or更改为and上面的代码。

rextester示例演示:http://rextester.com/MSVVN6153

答案 1 :(得分:0)

您即将离线 - 您需要在BC表格中同时加入AND而不是OR条件中的where

SELECT COUNT(DISTINCT A.G)
FROM A
LEFT JOIN B ON A.G = B.G
LEFT JOIN C ON A.G = C.G
WHERE B.G IS NULL
AND C.G IS NULL;

答案 2 :(得分:0)

我怀疑你想要:

select count(*)
from a
where not exists (select 1 from b where a.g = b.g) and
      not exists (select 1 from c where a.g = c.g);

您指定:“在A ...中,不在B或C中”。这表明G 中不存在BC中不存在。因此and而不是or(与您的查询版本一样)。

我也删除了count(distinct)。本能表明a.g是唯一的。如果没有,那么count(distinct a.g)是正确的。

答案 3 :(得分:0)

你应该学习使用set运算符的最后一个选项。为了证明正确性,我会留意数:

set nocount on;
declare @a table (id smallint not null); 
declare @b table (id smallint not null, xx smallint not null); 
declare @c table (id smallint not null, yy smallint not null); 

insert @a(id) values (1), (2), (3), (4);
insert @b(id, xx) values (1,0), (1,1), (3, 0); 
insert @c(id, yy) values (1,9), (2, 1), (2,2), (5,1); -- notice the value 5 does not exist in @a

select id from @a except 
select id from @b except 
select id from @c
;