Даны 2 набора данных вида:
DECLARE @Свойства TABLE (Лицевой INT, Параметр INT, Значение INT);
INSERT INTO @Свойства
VALUES (1,1,1)
,(1,2,1)
,(1,1,5)
,(2,1,1)
,(2,1,5)
,(2,2,7);
DECLARE @filter TABLE (Параметр INT,Значение INT)
INSERT INTO @filter
VALUES (1,5),(2,7);
Задача: Найти такие значения @Свойства.Лицевой, для которых выполняется условие фильтра по параметрам:
Все комбинации Параметр/Значение, содержащиеся в наборе @filter обязательно присутствуют на таких лицевых. Наличие других параметров или других значений для указанных параметров не имеет значения.
два варианта придумал по большому счету аналогичных:
[sql]
select
sv.Лицевой
from (
select distinct Лицевой, Параметр, Значение from @Свойства
) sv
join (
select distinct
f.Параметр as par,
f.Значение as val
from @filter f
) s on s.par = sv.Параметр and s.val = sv.Значение
group by sv.Лицевой
having count(1) = (
select count(1) from (
select count(1) cnt from @filter
group by Параметр, Значение
) s )
DECLARE @СвойстваUq TABLE (Лицевой INT, Параметр INT, Значение INT)
insert into @СвойстваUq(Лицевой, Параметр, Значение)
select distinct Лицевой, Параметр, Значение from @Свойства
DECLARE @filterUq TABLE (Параметр INT,Значение INT)
insert into @filterUq
select distinct Параметр, Значение from @filter
declare @filterCnt int
select @filterCnt = count(1) from @filterUq
select
sv.Лицевой
from @СвойстваUq sv
join @filterUq f on f.Значение = sv.Значение and f.Параметр = sv.Параметр
group by sv.Лицевой
having count(1) = @filterCnt
Здравствуйте, Kaifa, Вы писали:
K>K>DECLARE @СвойстваUq TABLE (Лицевой INT, Параметр INT, Значение INT)
K>insert into @СвойстваUq(Лицевой, Параметр, Значение)
K>select distinct Лицевой, Параметр, Значение from @Свойства
K>DECLARE @filterUq TABLE (Параметр INT,Значение INT)
K>insert into @filterUq
K>select distinct Параметр, Значение from @filter
K>declare @filterCnt int
K>select @filterCnt = count(1) from @filterUq
K>select
K>sv.Лицевой
K>from @СвойстваUq sv
K>join @filterUq f on f.Значение = sv.Значение and f.Параметр = sv.Параметр
K>group by sv.Лицевой
K>having count(1) = @filterCnt
K>
Нормальный вариант. Непонятно только, для чего делать копию данных. Достаточно просто уровень изоляции выставить подходящий.
Ну, или просто посчитать каунт в рамках стейтмента:
select
sv.Лицевой
from @Свойства sv
join @filter f on f.Значение = sv.Значение and f.Параметр = sv.Параметр
group by sv.Лицевой
having count(1) = (select count(1) from @filter)
S>select
S>sv.Лицевой
S>from @Свойства sv
S>join @filter f on f.Значение = sv.Значение and f.Параметр = sv.Параметр
S>group by sv.Лицевой
S>having count(1) = (select count(1) from @filter)
не сработает, если есть дублирующиеся значения в фильте или свойствах. например:
DECLARE @Свойства TABLE (Лицевой INT, Параметр INT, Значение INT);
INSERT INTO @Свойства
VALUES (1,1,1)
,(1,2,1)
,(1,1,5)
,(1,1,5)
,(2,1,1)
,(2,1,5)
,(2,2,7)
,(2,2,7)
,(2,2,7)
DECLARE @filter TABLE (Параметр INT,Значение INT)
INSERT INTO @filter
VALUES (1,5),(2,7), (2,7), (1, 1);