我已经搜索过这个并且似乎无法找到答案。我提前道歉,因为我确定这个答案已经存在,但我似乎无法找到答案。
我正在使用SQL Server 2005数据库,并且我知道下面的查询并不代表规范化的数据库,因为numPlacements字段同时位于详细信息和汇总表中。我没有创建数据库。
下面的SQL给出了使用where子句时的预期结果。预期结果是两个表中缺少匹配值的所有行,或者这两个值不匹配。
但是,如果我注释where子句并取消注释ON子句中的最终AND,它将返回超过200k行而不是预期的120个结果。
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,我们得到三个预期的行:
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