0

好吧,我花了一些時間研究這個,但似乎無法找到一個好的解決方案。如何使用表值參數進行條件JOIN?

我目前正在創建一個採用一組可選參數的存儲過程。存儲過程將充當多個表和列的「通用搜索查詢」。

存儲過程看起來是這樣的(請記住,這僅僅是一個精簡版和實際存儲的過程有更多的列等)

的「@ProductIdsParam intList中READONLY」是價值的示例表參數,如果它不是空的,我想加入。換句話說,查詢只能通過非空/空參數進行搜索。

調用該過程並解析其他參數的工作方式與此類似。然而,我可能誤解了,不應該像這樣做一個「通用搜索查詢」。

CREATE PROCEDURE [dbo].[usp_Search] 

    @ProductIdParam INT = NULL, 
    @CustomerNameParam NVARCHAR(100) = NULL, 
    @PriceParam decimal = NULL, 

    -- THIS IS WHAT I'D LIKE TO JOIN. BUT THE TABLE CAN BE EMPTY 
    @ProductIdsParam IntList READONLY 

AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT DISTINCT 

    CustomerTransactionTable.first_name AS FirstName, 
    CustomerTransactionTable.last_name AS LastName, 
    ProductTable.description AS ProductDescription, 
    ProductTable.price as ProductPrice 

FROM dbo.customer AS CustomerTransactionTable 

-- JOINS 
LEFT JOIN dbo.product AS ProductTable 
     ON CustomerTransactionTable.product_id = ProductTable.id 


WHERE 
    (ProductTable.id = @ProductIdParam OR @ProductIdParam IS NULL) 
    AND (CustomerTransactionTable.first_name = @CustomerNameParam OR @CustomerNameParam IS NULL) 
    AND (CustomerTransactionTable.price = @PriceParam OR @PriceParam IS NULL) 

END 
+0

你也可以使用動態sql查詢 – Ravi

回答

2

您可以在LEFT join中添加int表,然後根據過濾器表中的記錄計數添加where條件。如果將@ProductIdsParam聲明爲table,則應首先對其中的記錄進行計數並將結果存儲在變量中。

AND COALESCE(@ProductIdsParam.id, 0) = (CASE WHEN @ProductIdsCount = 0 THEN 0 ELSE ProductTable.id END) 

如果@ProductIdsCount = 0,那麼你總是得到0 = 0,所以你得到的所有記錄,否則你只能選擇其中的productId的過濾表等於ProductTable.id記錄。

雖然還有其他(也許更乾淨)的方法,但我認爲這可行。

+0

非常感謝Giulio。 我其實正在編輯我的文章,因爲我用類似的東西解決了它。但是,相反,我聲明瞭一個新的int,它獲得記錄計數,然後在where子句中對其進行檢查。我認爲你的方式是清潔雖然:) –

+1

我認爲開關條件是非常沉重,如果你有這麼多的條件或太多的數據那麼你的SQL查詢將是非常緩慢 – Ravi

+0

@Ravi感謝您的評論!我確實從未在最終解決方案中使用切換。我會盡力讓som的時間在我的問題上發佈最終的解決方案! –

相關問題