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的时间在我的问题上发布最终的解决方案! –

相关问题