0

我已经搜索过这个,似乎无法找到答案。我提前道歉,因为我确定这个答案就在那里,但我似乎找不到它。

我正在使用 SQL Server 2005 数据库,并且我知道下面的查询并不代表规范化的数据库,因为 numPlacements 字段在详细信息表和汇总表中。我没有创建数据库。

当使用 where 子句时,下面的 SQL 给出了预期的结果。预期结果是任一表中缺少匹配值或两个值不匹配的所有行。

但是,如果我注释 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
4

0 回答 0