0

有谁知道为什么以下 2 个查询的结果与第 3 个查询的结果不相加?

SELECT COUNT(leadID) FROM leads 
WHERE makeID NOT IN (SELECT uploadDataMapID FROM DG_App.dbo.uploadData WHERE uploadID = 3 AND uploadRowID = 1)
AND modelID NOT IN (SELECT uploadDataMapID FROM DG_App.dbo.uploadData WHERE uploadID = 3 AND uploadRowID = 2)

SELECT COUNT(leadID) FROM Leads 
WHERE makeID IN (SELECT uploadDataMapID FROM DG_App.dbo.uploadData WHERE uploadID = 3 AND uploadRowID = 1)
OR modelID IN (SELECT uploadDataMapID FROM DG_App.dbo.uploadData WHERE uploadID = 3 AND uploadRowID = 2)

SELECT COUNT(leadID) FROM Leads

第一个查询是我需要的计数。第二个是根据 DG_App.dbo.uploadData 表的内容告诉用户有多少条记录被抑制。第三个查询只是对所有记录的直接计数。

当我运行这些查询 1 的结果 + 查询 2 的结果时,出现的记录比整个表的计数少约 46K。我玩过用 () 对 WHERE 语句进行分组,但这根本没有改变计数。

这是 MSSQL 服务器 2012。

对此的任何输入都会很棒。

谢谢

4

3 回答 3

4

你有任何 NULL 值吗?他们不会出现在第一次也不会出现在第二次计数中,我认为你错过了那些。

SELECT Count(leadID) FROM Leads WHERE makeID is Null or modelID is null

编辑:我必须添加更多注意事项:因为有一个 AND 和一个 OR 条件,事情变得有点复杂!

  • Null IN ()始终被评估为Null,不会出现行
  • Null NOT IN ()总是被评估为Null,行不会出现
  • Null AND Something被评估为NullFalse,不会出现行
  • 如果 Something 为True ,则Null OR Something被评估为True,否则被评估为Null,只会出现一些行

这意味着在您的前两个查询中,一些带有 Null 的记录已经被计算在内,而另一些则没有。这是你想念的:

  • 您错过了两者makeIDmodelID为空的记录:

    SELECT Count(leadID) FROM Leads WHERE makeID is Null and modelID is null
    
  • 但是您也错过了makeID为 NullmodelID且不为空且不在第二个子查询中的记录:

    SELECT Count(leadID) FROM Leads
    WHERE makeID is Null
    AND modelID NOT IN (...)
    
  • 还有那些modelID为空makeID且不在第一个子查询中的:

    SELECT Count(leadID) FROM Leads
    WHERE makeID is NOT IN (...)
    AND modelID is Null
    
于 2012-11-09T00:14:00.293 回答
2

我能想到的三个案例:

  • uploadDataMapID的uploadID等于 3
  • uploadDataMapID的uploadRowID等于 1 或 2
  • 您的潜在客户表中有 NULL makeIDmodelID条目

SELECT count(leadID) FROM leads WHERE makeID IS NULL OR modelID IS NULL

SELECT count(leadID) 
FROM leads AS l INNER JOIN DG_App.dbo.uploadData AS u ON l.makeID = u.uploadDataMapID
WHERE u.uploadID <> 3 OR u.uploadRowID <> 1

SELECT count(leadID)
FROM leads AS l INNER JOIN DG_App.dbo.uploadData AS u ON l.modelID = u.uploadDataMapID
WHERE u.uploadID <> 3 OR u.uploadRowID <> 2

这三个查询应该为您提供丢失的记录。

于 2012-11-09T01:08:43.597 回答
1

这里有一些解释。

-- sample tables to discuss
create table innotintest (a int);
insert into innotintest values (1),(2),(3),(4),(null);
create table other (b int);
insert into other values (2),(3);
create table other1 (c int);
insert into other1 values (2),(3),(null);

select * from innotintest where a not in (select b from other); -- RESULT = 1,4
select * from innotintest where a in (select b from other);     -- RESULT = 2,3
--Overall outcome : Record with a=NULL is missing. It is neither IN nor NOT IN

select * from innotintest where a not in (select c from other1); -- RESULT = (none!)
select * from innotintest where a in (select c from other1);     -- RESULT = 2,3
--Overall outcome : Record with a=NULL is missing
--                  Moreover, when other1 contains NULL values,
--                            NOTHING is returned for NOT IN

重申代码中的注释

  1. NULL既不是IN()也不是NOT IN()
  2. 当集合NOT IN(...)中包含NULL时,不会匹配过滤器
于 2012-11-09T01:06:19.623 回答