私はこれを検索しましたが、答えが見つからないようです。この答えがそこにあると確信しているので、前もってお詫び申し上げますが、見つけられないようです。
SQL Server 2005 DB を使用していますが、numPlacements フィールドが詳細テーブルとロールアップ テーブルの両方にあるため、以下のクエリが正規化された DB を表していないことを認識しています。私はDBを作成しませんでした。
以下の SQL は、where 句が使用されている場合に期待される結果を示します。期待される結果は、いずれかのテーブルに一致する値がないか、2 つの値が一致しないすべての行です。
ただし、WHERE 句をコメントし、ON 句の最後の AND のコメントを外すと、予想される 120 の結果ではなく、20 万行を超える行が返されます。
SELECT CASE WHEN A.ID is NULL THEN B.ID ELSE A.ID END,
A.numPlacements AS 'AnumPlacements',
B.numPlacements AS 'bnumPlacements',
B.numPlacements - A.numPlacements as 'Variance'
FROM (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM PlacementDetailLevel
GROUP BY ID) A
FULL OUTER JOIN (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM PlacementRollupLevel
GROUP BY ID) B
ON A.ID = B.ID
--AND B.numPlacements <> A.numPlacements
WHERE A.numPlacements <> B.numPlacements or A.numPlacements is null or B.numPlacements is null
理由についてのアイデアはありますか?
ypercube の提案に基づく以下の詳細:
TableA と TableB を作成しました。それらは次のようになります。
TableA
ID numPlacements
1 10
2 20
3 30
4 40
TableB
ID numPlacements
2 20
3 31
4 40
5 50
違いは、TableA には #5 がなく、TableB には #1 がなく、#3 には両方で異なる numPlacements があることに注意してください。
SELECT CASE WHEN A.ID is NULL THEN B.ID ELSE A.ID END AS 'ID',
A.numPlacements AS 'AnumPlacements',
B.numPlacements AS 'BnumPlacements',
B.numPlacements - A.numPlacements as 'Variance'
FROM (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableA
GROUP BY ID) A
FULL OUTER JOIN (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableB
GROUP BY ID) B
ON A.ID = B.ID
上記はまさに私が期待するものを生成します:
ID AnumPlacements BnumPlacements Variance
1 10 NULL NULL
2 20 20 0
3 30 31 1
4 40 40 0
5 NULL 50 NULL
WHERE 句を追加してみましょう。
SELECT CASE WHEN A.ID is NULL THEN B.ID ELSE A.ID END AS 'ID',
A.numPlacements AS 'AnumPlacements',
B.numPlacements AS 'BnumPlacements',
B.numPlacements - A.numPlacements as 'Variance'
FROM (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableA
GROUP BY ID) A
FULL OUTER JOIN (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableB
GROUP BY ID) B
ON A.ID = B.ID
WHERE A.numPlacements <> B.numPlacements or A.numPlacements is null or B.numPlacements is null
where を使用すると、予想される 3 つの行が得られます。
ID AnumPlacements BnumPlacements Variance
1 10 NULL NULL
3 30 31 1
5 NULL 50 NULL
AND を追加してみましょう。
SELECT CASE WHEN A.ID is NULL THEN B.ID ELSE A.ID END AS 'ID',
A.numPlacements AS 'AnumPlacements',
B.numPlacements AS 'BnumPlacements',
B.numPlacements - A.numPlacements as 'Variance'
FROM (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableA
GROUP BY ID) A
FULL OUTER JOIN (SELECT ID,
Sum(numPlacements) AS 'numPlacements'
FROM TableB
GROUP BY ID) B
ON A.ID = B.ID
AND B.numPlacements <> A.numPlacements
ここで、結合で上記の AND を使用して試してみると、行 #3 が得られると予想されます。代わりに、これを取得します:
ID AnumPlacements BnumPlacements Variance
1 10 NULL NULL
2 NULL 20 NULL
2 20 NULL NULL
3 30 31 1
4 NULL 40 NULL
4 40 NULL NULL
5 NULL 50 NULL