2011-05-04 2 views
2

이 스크립트를 작성했습니다. WHERE 절의 두 부분을 주석 처리하면 결과에서 일부 행이 무시됩니다. 왜 누군가 말해 줄 수 있니?진정한 결과를 얻으려면 어디서나 완벽하게 참여하십시오.

첫 번째 쿼리에서는 FULL OUTER JOIN으로 작동하지만 두 번째 쿼리에서는 UNKNOWN 조건이 해결되는 WHERE 절을 사용하는 경우에도 쿼리가 INNER JOIN으로 반환되고 한 행만 반환됩니다.

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 
+0

실제 샘플 출력을 보여주십시오

난 당신이 원하는 생각합니다. 코드를 실행시키지 마십시오. – Gabe

답변

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 
+0

Quassnoi에게 감사하지만, 그렇지 않습니다. 나는 SQL이 FULL OUTER JOIN을하기를 원하지만, WHERE에 추가 ​​표현식을 추가해야만하고 이유를 모른다. – aporia

+0

@ vaporia : 원하는 결과 집합을 게시 할 수 있습니까? – Quassnoi

+0

게시물 끝에 예상 출력을 추가합니다. 이는 첫 번째 쿼리의 결과입니다. 마지막 질의가 논리적으로 반환되어야한다고 생각합니다. – aporia

관련 문제