Как сделать пересечение SQL с табличным параметром? - PullRequest
0 голосов
/ 20 апреля 2019

Мне нужно сделать перекресток и получить общее 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

Я получаю желаемый вариант: ID варианта: 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 голосов
/ 20 апреля 2019

Одним из вариантов является использование динамического SQL для создания запроса с несколькими операторами пересечения.

Или просто используйте JOIN для VariantValues ​​с OptionValue.Затем используйте 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 )
.
...