如何使 SQL 与 table 值参数相交?

How to make SQL intersection with table-valued parameter?

我需要做一个交集并获得共同点variantID;来自参数对列表 (optionID,valueID).

示例:对于包含 2 个项目的给定列表:

我手动编写了以下查询:

select * 
from tbl_VariantValues
where optionID = 16 and valueID = 1 and productID = 399 

select * 
from tbl_VariantValues
where optionID = 17 and valueID = 4 and productID = 399

我得到这些结果:

productID  variantID  optionID  valueID
---------------------------------------
399        11         16        1
399        12         16        1
399        13         16        1
399        14         16        1
399        15         16        1

productID  variantID  optionID  valueID
---------------------------------------
399        13         17        4
399        19         17        4

因为我只需要variantID,有交集:

select variantID 
from tbl_VariantValues
where optionID = 16 
  and valueID = 1 
  and productID = 319 

intersect 

select variantID 
from tbl_VariantValues
where optionID = 17 
  and valueID = 4 
  and productID = 319

我得到了想要的结果 variantID:13

问题是我想以编程方式执行上述查询,因为 tvp 列表中可以有更多项目。可能吗?

我尝试编写以下查询,但不知道在哪里以及如何放置相交:

create procedure [dbo].[getVariantID]
    (@list OptionValueList readonly)
as
begin 
    declare @UseTVP int
    set @UseTVP = (select count(*) from @list) 

    select variantID
    from dbo.tbl_VariantValues
    where (optionID = (select C.OptionID from @list C) 
      and valueID = (select C.OptionID, C.ValueID from @list C)
       or @UseTVP = 0)
    intersect
end

@UseTVP 是 tvp 项目的计数,我需要在这里使用相交逻辑来合并表格。或者还有其他方法吗?

一个选项是使用动态 SQL 创建具有多个相交运算符的查询。

或者仅对具有 OptionValue 的 VariantValues 使用 JOIN。然后使用 GROUP BY + HAVING 让用户所有的 OptionValue 都匹配

; with 
--  generate sample table tbl_VariantValues
tbl_VariantValues as
(
    select  productID = 399, variantID = 11, optionID = 16, valueID = 1 union all
    select  productID = 399, variantID = 12, optionID = 16, valueID = 1 union all
    select  productID = 399, variantID = 13, optionID = 16, valueID = 1 union all
    select  productID = 399, variantID = 14, optionID = 16, valueID = 1 union all
    select  productID = 399, variantID = 15, optionID = 16, valueID = 1 union all

    select  productID = 399, variantID = 13, optionID = 17, valueID = 4 union all
    select  productID = 399, variantID = 14, optionID = 17, valueID = 4 union all
    select  productID = 399, variantID = 19, optionID = 17, valueID = 4 union all

    select  productID = 399, variantID = 13, optionID = 18, valueID = 5 union all
    select  productID = 399, variantID = 15, optionID = 18, valueID = 5 union all
    select  productID = 399, variantID = 19, optionID = 18, valueID = 5
),
--  your OptionValue sample
OptionValueList  as
(
    select  productID = 399, optionID = 16, valueID = 1 union all
    select  productID = 399, optionID = 17, valueID = 4 union all
    select  productID = 399, optionID = 18, valueID = 5
)
--  the query
select  v.variantID
from    tbl_VariantValues v
        inner join OptionValueList o    on  v.productID = o.productID
                                       and  v.optionID  = o.optionID
                                       and  v.valueID   = o.valueID
group by v.variantID
having count(*) = (select count(*) from OptionValueList )