2012-09-26 41 views
3

我收到來自針對Micrsoft SQL Server 2008(10.0.1600.22/Service Pack 2)的查詢的意外結果。查詢忽略WHERE子句中的過濾

它可能是一個錯誤?

我試圖創建一個類似的查詢來複制問題 - 沒有成功。所以我猜這個查詢本身沒有問題,但其他的東西卻導致了這種奇怪的行爲。

我希望對可能導致問題的一些建議。

首先,來看看這個工作例如:

DROP TABLE #TempType 
DROP TABLE #TempData 

SELECT * INTO #TempType FROM (
    SELECT 1 AS Id, 10 AS TempDataFK, 'Do' AS Name, 'CODE1' AS Type UNION 
    SELECT 2 AS Id, 10 AS TempDataFK, 'Re' AS Name, 'CODE2' AS Type UNION 
    SELECT 3 AS Id, 20 AS TempDataFK, 'Mi' AS Name, 'CODE2' AS Type UNION 
    SELECT 5 AS Id, 10 AS TempDataFK, 'Fa' AS Name, 'CODE3' AS Type UNION 
    SELECT 6 AS Id, 20 AS TempDataFK, 'So' AS Name, 'CODE4' AS Type 
) sub 

SELECT * INTO #TempData FROM (
    SELECT 10 AS Id, 150 AS Number UNION 
    SELECT 20 AS Id, 150 AS Number UNION 
    SELECT 30 AS Id, 150 AS Number UNION 
    SELECT 40 AS Id, 180 AS Number 
) sub 

SELECT C1.Name Name1, 
     C2.Name Name2, 
     C3.Name Name3, 
     C4.Name Name4, 
     #TempData.Id, 
     #TempData.Number 
FROM #TempData 
    LEFT JOIN #TempType C1 (NOLOCK) 
     ON #TempData.Id = C1.TempDataFK 
     AND C1.Type = 'CODE1' 
    LEFT JOIN #TempType C2 (NOLOCK) 
     ON #TempData.Id = C2.TempDataFK 
     AND C2.Type = 'CODE2' 
    LEFT JOIN #TempType C3 (NOLOCK) 
     ON #TempData.Id = C3.TempDataFK 
     AND C3.Type = 'CODE3' 
    LEFT JOIN #TempType C4 (NOLOCK) 
     ON #TempData.Id = C4.TempDataFK 
     AND C4.Type = 'CODE4' 
WHERE 1=1 
    AND (#TempData.Number = 150) 
    AND (C1.Name='Mi' OR C2.Name='Mi' OR C3.Name='Mi' OR C4.Name='Mi') 

正如你可以看到我左側的接合部表TempTypeTempData四倍。每次給它一個不同的別名。然後我過濾一定數量(150),並希望至少有一個名稱應該是'Mi'。

結果不出所料:

-------------------------------------------- 
Name1 Name2 Name3 Name4 Id Number 
NULL Mi  NULL So  20 150 
-------------------------------------------- 

不過,如果我運行一個類似的查詢對我的客戶數據庫中,我得到:

-------------------------------------------- 
Name1 Name2 Name3 Name4 Id Number 
Do  Re  Fa  NULL 10 150 
NULL Mi  NULL So  20 150 
NULL NULL NULL NULL 30 150 
-------------------------------------------- 

這是因爲如果類似(C1.Name='Mi' OR C2.Name='Mi' OR C3.Name='Mi' OR C4.Name='Mi')的一部分,不使用在過濾中。

不同的查詢,但相同的結構
在客戶數據庫中的表是不是暫時的,它們已經包含數據。桌子也有其他各種各樣的領域,但我仍然只剩下一張桌子。所以結構與上面相同。

無法在新的數據庫複製
我試圖只用表和受影響的字段創建一個新的數據庫複製的問題 - 在複製的問題沒有更迭。

模式
值得一提的是客戶數據庫包含幾個模式。兩個類似於TempData和TempType的表都屬於同一個模式(不是dbo)。 此外,與TempType.Type類似的字段是另一個模式中另一個表的外鍵,但由於我們沒有加入,所以我沒有看到它是相關的?

另一個特點
如果我把C1.Name等,爲我的選擇的一部分,就像這樣:

SELECT C1.Name Name1, 
     C2.Name Name2, 
     C3.Name Name3, 
     C4.Name Name4, 
     #TempData.Id, 
     #TempData.Number, 
     CASE WHEN (C1.Name = 'Mi' AND C1.Name IS NOT NULL) THEN 1 ELSE 0 END, 
     CASE WHEN (C2.Name = 'Mi' AND C2.Name IS NOT NULL) THEN 1 ELSE 0 END, 
     CASE WHEN (C3.Name = 'Mi' AND C3.Name IS NOT NULL) THEN 1 ELSE 0 END, 
     CASE WHEN (C4.Name = 'Mi' AND C4.Name IS NOT NULL) THEN 1 ELSE 0 END 

我得到對我的客戶數據庫中所預期的結果(只有一行):

Name1 Name2 Name3 Name4 Id Number (No column name) (No column name) (No column name) (No column name) 
NULL Mi  NULL So  20 150  0     1     0     0 


任何建議,這可能是導致此?

+0

你說你正在運行一個不同的查詢。你能告訴我們那個查詢嗎?如果該查詢使用相同的地方,那麼()可能是Or中和AND中的優先問題。另外,爲什麼1 = 1在哪裏? –

+2

不是說這可以解決問題,但請注意'LEFT JOIN a ... WHERE a.something = something'將其變成了'INNER JOIN'。您可能需要將C1上的「過濾器」移動到聯接的ON子句中,而不是查詢的過濾器子句。 –

+0

@ElVieejo我無法顯示原始查詢(因爲它包含特定於客戶端的字段名稱),但結構是100%相似的。也是括號。 1 = 1只是爲了更容易的調試(註釋掉例如「AND(#TempData.Number = 150)」) –

回答