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

时间:2019-04-20 09:06:45

标签: sql-server intersect table-valued-parameters

我需要建立一个交叉点并获得一个variantID的共同点;来自参数对(optionID,valueID)的列表。

示例:对于其中有2个项目的给定列表:

  • optionID = 16并且valueID = 1
  • optionID = 17,valueID = 4

我手动编写了以下查询:

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项的计数,在这里我需要一种相交用法的逻辑来合并表。还是有其他方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

一种选择是使用动态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 )