2014-04-01 62 views
0

我在一個相當長的查詢,在某些時候,我有這樣的:內部查詢JOIN

LEFT OUTER JOIN T1 ON T1.ID = T2.ID 

自從我得到不正確的結果從我的查詢(太多行),我正在工作對此,當我試過這個:

LEFT OUTER JOIN (SELECT * FROM T1) T1 ON T1.ID = T2.ID 

然後得到我想要的。我想知道爲什麼這兩行有不同的結果。有人可以向我解釋嗎?

P.S.我使用SQL Server 2008.

編輯2:我發佈了一個video on YouTube顯示問題。

編輯1:這裏是顯示問題的完整最小查詢:

SELECT 
    Project.ProjectID, 
    Contract.ContractID, 
    BookletStatus.PrintStatusID AS StatusID 
FROM 
    Project 
    INNER JOIN Contract ON Contract.ContractID = Project.SignedContractID 
    INNER JOIN BookProject ON BookProject.ProjectID = Project.ProjectID 
    LEFT OUTER JOIN (SELECT * FROM Booklet) Booklet1 ON Booklet1.ContractID = Contract.ContractID 

    INNER JOIN PrintStatus AS CoverStatus ON BookProject.CoverStatusID = CoverStatus.PrintStatusID 

    INNER JOIN PrintStatus AS BookletStatus ON 
    (CASE 
     WHEN Booklet1.Qty > 0 THEN BookProject.BookletStatusID 
     ELSE -10 
    END) = BookletStatus.PrintStatusID 

下面是結果,與內查詢 「(SELECT * FROM小冊子)Booklet1」:

ProjectID ContractID StatusID 
    501  1356  -10 
    502  1317  -10 
    503  1371  -10 
    ... 

而且結果沒有內部查詢(僅使用「小冊子Booklet1」):

ProjectID ContractID StatusID 
    501  1356  -10 
    501  1356  0 
    501  1356  10 
    501  1356  15 
    501  1356  20 
    ... 
    502  1317  -10 
    502  1317  0 
    502  1317  10 
    502  1317  15 
    502  1317  20 
    ... 
    503  1371  -10 
    503  1371  0 
    503  1371  10 
    503  1371  15 
    503  1371  20 
    ... 
+3

可能不會得到太多的幫助,除非你能重現該問題與一個小而完整的查詢,並解釋你得到什麼樣的複製品。也許嘗試一個較小的查詢,只用前面的表'SELECT * FROM T2 LEFT OUTER JOIN T1 ...'來查看它是否演示了這個問題,然後查詢就會更小,並且可以發佈完整的查詢。 **如果您不能像這樣重現問題,那麼這表明查詢的其餘部分對您所看到的行爲有所貢獻,而不僅僅是您發佈的片段。** – AaronLS

+0

出於好奇,它是否會使任何如果您將子查詢上的別名從T1更改爲T1_Derived,那麼區別如何? LEFT OUTER JOIN(SELECT * FROM T1)T1_Derived ON T1_Derived.TheID = T2.TheID。它不應該,但是在一個微不足道的差異中,我認爲它影響了實際的執行計劃。 –

+0

@KarlKieninger我試過了,它沒有區別(我用一個別名或另一個獲得不同的行)。一些讓我撓頭的東西:我在SQL Server 2008的開發機器上得到了這些結果;但是當我在生產服務器上備份/恢復完整的數據庫時,運行SQL Server 2008 R2時,我總是獲得不同的行。換句話說,我的原始查詢(沒有內部查詢)在兩臺機器上的表現都不一樣。 – ConnorsFan

回答

-1

只要我能,我將檢查SQL Server 2008的更新是否有所作爲。我在網上看到了一些有關2008年版SQL Server中的bug的評論。

+0

這絕不是SQL Server中的一個錯誤...尤其不是JOIN中的錯誤。到目前爲止,SQL Server執行了多少萬億次連接?該論壇中的人指責SQL Server錯誤。您的查詢可能是非確定性的。因此,查詢中的隨機更改可能會導致結果發生更改。 – usr

+0

那麼,爲什麼兩臺服務器的結果不一樣?我提醒你,它們是同一個數據庫的兩個副本(使用備份/恢復)。因此,相同的表結構,相同的查詢,相同的數據;但結果不同。 – ConnorsFan

+0

不同的查詢計劃或查詢計劃是非確定性的(並行性,無序預取,不區分大小寫的分組......)。查詢結果可以很容易地不確定。 – usr

0

您是否會遇到處理空值的不同設置問題?如果QTY在ansi null設置不同的機器上可能爲null,我可以看看下面的代碼可能會有不同的評估。

ON 
    (CASE 
     WHEN Booklet1.Qty > 0 THEN BookProject.BookletStatusID 
     ELSE -10 
    END) = BookletStatus.PrintStatusID 
+0

查詢開始時有一條語句SET ANSI_NULLS ON。此外,在實際生產查詢中(比本文中顯示的簡化版本要長得多),該行顯示爲:WHEN(Booklet1.Qty IS NOT NULL)AND(Booklet1.Qty> 0)THEN ...我刪除了「IS NOT NULL「部分,因爲它對我在此處提交的問題沒有任何可觀察的影響。 – ConnorsFan