2012-01-10 120 views
2

我想創建條件連接到我的T-SQL查詢中的表。在本實施例中使用的表是從Northwind數據庫(只有一個附加表ProductCategories)有條件地連接表

表產品與表分類有許多一對多的關係,因此表ProductCategories進入圖片。

我需要的數量列於表訂單明細的每一種產品在一定的範疇下降的總和。所以我有一個像下面這樣的查詢

Select p.ProductName, Sum(od.Quantity) As Qty 
From Products p 
    Join OrderDetails od On od.ProductID = p.ProductID 
    Join ProductCategories pc On pc.ProductID = p.ProductID 
     And pc.CategoryID = @CategoryID 
Group By p.ProductName 

@CategoryID是一個可選參數。所以,如果它未提供,則加入到表ProductCategories不會被要求 和查詢應該看起來像一個下面

Select p.ProductName, Sum(od.Quantity) As Qty 
From Products p 
    Join OrderDetails od On od.ProductID = p.ProductID 
Group By p.ProductName 

我想要實現這個而不重複整個查詢如果條件(如下)

If @CategoryID Is Null 
    Select p.ProductName, Sum(od.Quantity) As Qty 
    From Products p 
     Join OrderDetails od On od.ProductID = p.ProductID 
    Group By p.ProductName 
Else 
    Select p.ProductName, Sum(od.Quantity) As Qty 
    From Products p 
     Join OrderDetails od On od.ProductID = p.ProductID 
     Join ProductCategories pc On pc.ProductID = p.ProductID 
      And pc.CategoryID = @CategoryID 
    Group By p.ProductName 

這被簡化,其具有許多其它表和類似ProductCategories條件查詢的版本。並且將需要多個多重條件和重複的查詢。我也嘗試動態生成查詢。它可以工作,但查詢根本不可讀。

任何解決方案? 謝謝。

回答

2

試試這個,如果你使用正確的參數化查詢 - 不會有任何性能影響,但可能會增加:

Select p.ProductName, Sum(od.Quantity) As Qty 
From Products p 
    Join OrderDetails od On od.ProductID = p.ProductID 
WHERE @CategoryID IS NULL OR EXISTS (SELECT * FROM ProductCategories WHERE CategoryID = @CategoryID AND ProductID = p.ProductID) 
Group By p.ProductName 

其實

在你的查詢,如果可以有多個行在ProductCategoriesOrderDetails中的一行 - 那麼你在你的SUM中得到od.Quantity的重複 - 它是一個預期的行爲?

+0

重複的od.Quantity是我想要避免的,這就是我不想加入表ProductCategories的原因,如果@CategoryID沒有提供 – Romeo 2012-01-10 04:58:59

+0

謝謝,它的工作原理。 – Romeo 2012-01-10 05:34:59

0

我不是很熟悉的T-SQL,所以我不知道這是否會削減,但在MySQL中,你可以做類似

Select p.ProductName, Sum(od.Quantity) As Qty 
From Products p 
    Join OrderDetails od On od.ProductID = p.ProductID 
    Join ProductCategories pc On pc.ProductID = p.ProductID 
     And pc.CategoryID = if(@CategoryID is null , pc.CategoryID, @CategoryId) 
Group By p.ProductName 

是,如果()仍然只是「一個查詢「,如果這就是你想要的。

同時,你說你能夠動態生成一個查詢。如果是這樣的話,可讀性很大程度上是一個問題?如果你生成的查詢比我上面建議的更高性能,我會去做。它產生了;你贏了'手動調整/閱讀結果。

+0

我知道你在想用這個 「而pc.CategoryID = IF(@類別ID爲空,pc.CategoryID,@的CategoryId)」 正確的語法 「而pc.CategoryID = CASE WHEN這裏做@類別ID爲空然後pc.CategoryID否@ @類別ID結束「 但是,它會讓我重複行(因爲ProductCategories可以包含單個產品的多個記錄) – Romeo 2012-01-10 05:06:31

0

我相信你可以將表加入到你正在做的隱式內部連接中。

在一個內連接其與在目標表中的鍵的每個實例上的源表中的密鑰相匹配。

在目標表中的匹配的每個實例產生一組顯示 匹配類型的行。

隨着外部聯接它將顯示源行即使存在在另一個表中沒有匹配的行。如果存在,它將與內部聯接基本相同,並且您會爲每個匹配實例返回一行。因此,您可以在需要時獲取所需的數據,而不必獲取無法獲取的數據。

拿這個作爲一個例子

select * from Products 

    Left join ProductAndCategory on ProductAndCategory.ProductID = Products.ProductID 
    left join Categories on Categories.CategoryID = ProductAndCategory.CategoryID 

如果我有一個簡單Product表一中ProductIDProductName一個ProductAndCategory表一中ProductIDCategoryIDCategories表一中CategoryIDCategoryName

它將顯示具有連接類別的類別的行,而沒有類別的行將僅顯示一行爲null的值不存在。

+0

左連接不能解決我的問題 – Romeo 2012-01-10 04:57:22