如何使用 table 值参数进行条件连接?

How to do a conditional JOIN with table valued parameter?

好的,所以我花了一些时间研究这个问题,但似乎找不到好的解决方案。

我目前正在创建一个带有一组可选参数的存储过程。存储过程将充当多个 table 和列的 "universal search query"。

存储过程看起来像这样(请记住,这只是精简版,实际存储过程有更多列等)

“@ProductIdsParam IntList READONLY”是一个 table 值参数示例,如果它不为空,我想加入。换句话说,查询应该只搜索不是 null/empty 的参数。

调用过程和解析其他参数的工作就像它应该的那样。然而,我可能误解了,根本不应该做这样的 "universal search query"。

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

您可以在 LEFT join 中添加 int table,然后在 filter table 中添加一个基于记录数的 where 条件。如果@ProductIdsParam声明为table,你应该先计算其中的记录并将结果存储在变量中。

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

如果@ProductIdsCount = 0 那么你总是得到 0 = 0 所以你得到所有记录,否则你 select 只记录过滤器 table 中的 productId 等于 ProductTable.id.

虽然还有其他(可能更清洁)的方法,但我认为这可行。