2011-08-16 97 views
3

我想執行一個SELECT查詢連接到一個LEFT JOIN連接表中可能沒有記錄的兩個表上。喜歡的東西:SQL Server - 選擇左連接NULL記錄在哪裏條件

--SELECT row using AreaID 
SELECT * 
FROM Rate 
LEFT JOIN Area 
ON Rate.AreaID = Area.AreaID 
WHERE ProductID = @ProductID 
AND Area.PostcodeOutcode = @PostcodeOutcode 

這工作時,在區表中存在@PostcodeOutcode,但我仍然需要退回紀錄左表如果沒有在正確的表中的記錄。

我目前捏造它通過這樣做,但我知道有一個更好的解決方案:

DECLARE @AreaID int 
SELECT @AreaID = AreaID 
FROM Area WHERE PostcodeOutcode = @PostcodeOutcode 

--SELECT row using AreaID 
SELECT * 
FROM Rate 
WHERE ProductID = @ProductID 
AND 
(
    AreaID = @AreaID 
    OR (@AreaID IS NULL AND AreaID IS NULL) 
) 

我知道這可能是簡單的,但我的SQL知識是有限的。請幫忙。

感謝

亞歷

+1

你確實在說SELECT *是一個SQL反模式?你的回報超過了你的需要(在最少的情況下連接字段重複),這對性能不利。生產代碼通常不應包含select *。 – HLGEM

回答

5

移動區域檢查聯接

SELECT * FROM Rate 
LEFT JOIN Area 
    ON Rate.AreaID = Area.AreaID and Area.PostcodeOutcode = @PostcodeOutcode 
WHERE ProductID = @ProductID 

更新的意見修改後的問題,這是你想要的嗎?

SELECT Rate.RatePercent FROM Rate 
INNER JOIN Area 
    ON Rate.AreaID = Area.AreaID and Area.PostcodeOutcode = @PostcodeOutcode 
WHERE 
    ProductID = @ProductID 
UNION ALL 
SELECT Rate.RatePercent FROM Rate 
where 
    ProductID = @ProductID 
and 
    AreaId is null 
and 
not exists(select PostCodeOutCode From Area where [email protected]) 
+0

也許我問了錯誤的問題。我只想返回一行。看到我上面的模糊解決方案。 即,如果_Area.PostcodeOutcode_ **不是** null,則返回來自連接的_Rate.RatePercent_。如果_Area.PostcodeOutcode_ **爲null,則返回_Rate.RatePercent_,其中_Rate.AreaID_爲null。 謝謝 亞歷克斯 – Alex

+0

就是這樣!謝謝。我期待或許更簡單一些。這比我目前的做法更有效率嗎? – Alex

+0

只是因爲它使用的是單個查詢而不是兩次提取,所以最好的方法是在查詢計劃器中查看兩個查詢,看看成本是多少 –

4

有左差別加入這兩者之間:

Select * 
From Table1 t1 
Left Outer Join Table2 t2 On t2.id = t1.id 
Where t2.somevalue = @SomeParameter 

而且

Select * 
From dbo.Table1 t1 
Left Outer Join dbo.Table2 t2 On t2.id = t1.id And t2.somevalue = @SomeParameter 

後者將過濾表2,而前者將過濾表1和表2之間的連接。所以,這意味着第一個查詢將連接id上的兩個表中的所有行,然後過濾某個值與參數不匹配的那些行,即通常也會過濾出somevalue爲null的那些行,因爲沒有行。

第二個查詢會將table1與table2連接到id,但是table2會首先在匹配參數上進行過濾,因此不匹配的行也會返回,因此不會被過濾掉。

另外還有一個提示:應該始終在查詢中提供表的模式(出於性能原因)。