FULL OUTER JOIN和WHERE获得真实结果?

时间:2011-05-04 12:27:46

标签: sql-server tsql

我写了这个脚本。如果我们在WHERE子句中注释这两部分,则会在结果中忽略某些行。有人可以告诉我为什么吗?

在第一个查询中,它作为FULL OUTER JOIN运行,但在第二个查询中,查询结果为INNER JOIN并且只返回一行,尽管使用了UNKNOWN条件解析的WHERE子句。

DECLARE @ALLDATA TABLE 
( 
[Id]        INT,
[T3Id]      INT,
[StockId]   INT,
[Serial]    INT,
[ISDel]     INT
)
INSERT INTO @ALLDATA ([Id],[T3Id],[StockId],[Serial],[ISDel])
Select 5 AS [Id],11 AS [T3Id],5 AS [StockId],0 AS [Serial],1 AS [ISDel]
UNION ALL
Select 1 AS [Id],11 AS [T3Id],5 AS [StockId],0 AS [Serial],1 AS [ISDel]
UNION ALL
Select 1 AS [Id],11 AS [T3Id],5 AS [StockId],1 AS [Serial],-1 AS [ISDel]
UNION ALL
Select 2 AS [Id],11 AS [T3Id],5 AS [StockId],2 AS [Serial],-1 AS [ISDel]
UNION ALL
Select 3 AS [Id],11 AS [T3Id],5 AS [StockId],3 AS [Serial],-1 AS [ISDel]
UNION ALL
Select 4 AS [Id],11 AS [T3Id],5 AS [StockId],4 AS [Serial],-1 AS [ISDel]

SELECT 'WITH CONDITIONS:'

SELECT 
 ISNULL(DataIns.[Id],DataDEL.[Id])      AS [Id]
,ISNULL(DataDEL.[StockId],-1)           AS [OLDStockId]
,ISNULL(DataDEL.[Serial],0)             AS [OLDSerial]
,ISNULL(DataIns.[StockId],-1)           AS [NEWStockId]
,ISNULL(DataIns.[Serial],0)             AS [NEWSerial]
,ISNULL(DataIns.[T3Id],DataDEL.[T3Id])  AS [T3Id]
,DataIns.[ISDel]                        AS [ISDel1]
,DataDEL.[ISDel]                        AS [ISDel2]
FROM @ALLDATA       AS DataIns
FULL OUTER JOIN @ALLDATA AS DataDEL 
ON 
DataDEL.Id = DataIns.Id 
AND  
DataDEL.ISDel = 1 
AND 
DataIns.ISDel = -1
WHERE ISNULL(DataDEL.[ISDel],1) = 1 AND ISNULL(DataIns.[ISDel],-1) = -1 

SELECT 'WITHOUT CONDITIONS:'

SELECT 
 ISNULL(DataIns.[Id],DataDEL.[Id])      AS [Id]
,ISNULL(DataDEL.[StockId],-1)           AS [OLDStockId]
,ISNULL(DataDEL.[Serial],0)             AS [OLDSerial]
,ISNULL(DataIns.[StockId],-1)           AS [NEWStockId]
,ISNULL(DataIns.[Serial],0)             AS [NEWSerial]
,ISNULL(DataIns.[T3Id],DataDEL.[T3Id])  AS [T3Id]
,DataIns.[ISDel]                        AS [ISDel1]
,DataDEL.[ISDel]                        AS [ISDel2]
FROM @ALLDATA       AS DataIns
FULL OUTER JOIN @ALLDATA AS DataDEL 
ON 
DataDEL.Id = DataIns.Id 
--AND 
--  DataDEL.ISDel = 1 
--AND 
--  DataIns.ISDel = -1
WHERE ISNULL(DataDEL.[ISDel],1) = 1 AND ISNULL(DataIns.[ISDel],-1) = -1 

期望的输出:

1    5  0    5  1   11    -1       1
2   -1  0    5  2   11    -1    NULL
3   -1  0    5  3   11    -1    NULL
4   -1  0    5  4   11    -1    NULL
5    5  0   -1  0   11  NULL       1

1 个答案:

答案 0 :(得分:3)

  

有人可以告诉我为什么吗?

因为这是FULL OUTER JOIN的工作方式。

当您在ON子句中注释掉其他条件时,实际上您获得了INNER JOIN(因为id将始终在自联接中产生至少一个匹配)

你的第一个查询对我来说也没有意义(或者你有一些非常复杂的要求)。

我相信你想要这个:

SELECT   ISNULL(DataIns.[Id],DataDEL.[Id])      AS [Id]
        ,ISNULL(DataDEL.[StockId],-1)           AS [OLDStockId]
        ,ISNULL(DataDEL.[Serial],0)             AS [OLDSerial]
        ,ISNULL(DataIns.[StockId],-1)           AS [NEWStockId]
        ,ISNULL(DataIns.[Serial],0)             AS [NEWSerial]
        ,ISNULL(DataIns.[T3Id],DataDEL.[T3Id])  AS [T3Id]
        ,DataIns.[ISDel]                        AS [ISDel1]
        ,DataDEL.[ISDel]                        AS [ISDel2]
FROM    (
        SELECT  *
        FROM    @alldata
        WHERE   isdel = 1
        ) dataDel
FULL JOIN
        (
        SELECT  *
        FROM    @alldata
        WHERE   isdel = -1
        ) dataIns
ON      dataDel.id = dataIns.id