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

最初のクエリは、必要なカウントです。2つ目は、DG_App.dbo.uploadDataテーブルの内容に基づいて抑制されたレコードの数をユーザーに通知することです。3番目のクエリは、すべてのレコードの単純なカウントです。

これらを実行すると、クエリ1の結果+クエリ2の結果は、テーブル全体の数よりも約46Kレコード少なくなります。WHEREステートメントを()でグループ化してみましたが、カウントはまったく変わりませんでした。

これはMSSQLServer2012です。

これに関するどんな入力も素晴らしいでしょう。

ありがとう

4

3 に答える 3

4

NULL値はありますか?それらは最初のカウントにも2番目のカウントにも表示されません。あなたはそれらを見逃していると思います。

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

編集:私はいくつかの考慮事項を追加する必要があります:ANDとOR条件があるので、物事はもう少し複雑になります!

  • Null IN()は常にNullとして評価され、行は表示されません
  • Null NOT IN()は常にNullとして評価され、行は表示されません
  • Null AND何かがNullまたはFalseとして評価され、行は表示されません
  • NullまたはSomethingTrueの場合はTrueと評価され、それ以外の場合はNullと評価され、一部の行のみが表示されます

これは、最初の2つのクエリで、Nullがすでにカウントされているレコードと、カウントされていないレコードがあることを意味します。これはあなたが見逃しているものです:

  • makeIDとが両方ともmodelIDNullであるレコードを見逃します。

    SELECT Count(leadID) FROM Leads WHERE makeID is Null and modelID is null
    
  • makeIDただし、がNullであり、modelIDnullでなく、2番目のサブクエリにないレコードも見逃します。

    SELECT Count(leadID) FROM Leads
    WHERE makeID is Null
    AND modelID NOT IN (...)
    
  • また、modelIDnullでmakeIDあり、最初のサブクエリにないもの:

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

私が考えることができる3つのケース:

  • uploadDataMapIDに3と等しくないuploadIDがあります
  • uploadDataMapIDに1または2と等しくないuploadRowIDがあります
  • リードテーブルにNULLのmakeIDまたはmodelIDエントリがあります

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

これらの3つのクエリは、欠落しているレコードを提供するはずです。

于 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. セットにNULLNOT IN(...)が含まれている場合、フィルターに一致するものはありません
于 2012-11-09T01:06:19.623 に答える