Maciej Los
Я не уверен, что хорошо вас понимаю...
Вам нужно разделиться @SPInput
около {'|', ','}
получить [Type]
и [Value]
Затем вы должны сравнить эти значения со значениями в таблице. Видеть:
DECLARE @tmp TABLE(ID int, CustomerID int, [Type] varchar(30), [Value] varchar(30))
INSERT INTO @tmp(ID, CustomerID, [Type], [Value])
VALUES(1, 1, 'T1', '123'),
(2, 1, 'T2', 'XYZ'),
(3, 1, 'T1', '456'),
(4, 2, 'T1', '789'),
(5, 1, 'T2', 'ABC'),
(6, 4, 'T1', '111')
DECLARE @SPInput varchar(150) = 'T1,123|T2,ABC|T1,456'
--split @SPInput by '|'
;WITH KeyPairs AS
(
--initial query
SELECT LEFT(@SPInput, CHARINDEX('|', @SPInput)-1) KeyPair, RIGHT(@SPInput, LEN(@SPInput)-CHARINDEX('|', @SPInput)) Remainder
WHERE CHARINDEX('|', @SPInput)>0
--recursive part
UNION ALL
SELECT LEFT(Remainder, CHARINDEX('|', Remainder)-1) KeyPair, RIGHT(Remainder, LEN(Remainder)-CHARINDEX('|', Remainder)) Remainder
FROM KeyPairs
WHERE CHARINDEX('|', Remainder)>0
UNION ALL
SELECT Remainder KeyPair, NULL Remainder
FROM KeyPairs
WHERE CHARINDEX('|', Remainder)=0
), TV AS --split KeyPair by ','
(
SELECT LEFT(KeyPair, CHARINDEX(',', KeyPair)-1) [Type], RIGHT(KeyPair, LEN(KeyPair)-CHARINDEX(',', KeyPair)) [Value]
FROM KeyPairs
WHERE CHARINDEX(',', KeyPair)>0
)
-- get data from @tmp table where type and value passed by @SPInput are equal
SELECT t1.*
FROM @tmp t1 INNER JOIN TV t2 ON t1.[Type] = t2.[Type] AND t1.[Value] = t2.[Value]
Результат:
ID CustomerID Type Value
1 1 T1 123
3 1 T1 456
5 1 T2 ABC
В приведенном выше примере я использую
КТОС[
^] для разделения входных данных на части, но вы также можете использовать другой способ:
Разделение строк с разделителями с помощью XML в SQL Server[
^]
Теперь вам нужно изменить код в соответствии с вашими потребностями.
Удачи вам!
[РЕДАКТИРОВАТЬ]
Что касается нашего обсуждения (в комментариях) этого условия:
(T1 AND (123 OR 456)) AND (T2 AND BC)
...
Самый простой способ фильтрации данных на основе вышеуказанного условия-использовать клиентский код (c#, vb.net и т. д.). см.:
//crate sample data
DataTable tmp = new DataTable();
tmp.Columns.AddRange(new DataColumn[]
{
new DataColumn("ID", typeof(int)),
new DataColumn("CustomerID", typeof(int)),
new DataColumn("Type", typeof(string)),
new DataColumn("Value", typeof(string))
});
tmp.Rows.Add(new object[]{1, 1, "T1", "123"});
tmp.Rows.Add(new object[]{2, 1, "T2", "XYZ"});
tmp.Rows.Add(new object[]{3, 1, "T1", "456"});
tmp.Rows.Add(new object[]{4, 2, "T1", "789"});
tmp.Rows.Add(new object[]{5, 1, "T2", "ABC"});
tmp.Rows.Add(new object[]{6, 4, "T1", "111"});
//determine values to find
KeyValuePair<string, string>[] values2find = new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("T1", "123"),
new KeyValuePair<string, string>("T2", "BC"),
new KeyValuePair<string, string>("T1", "456")
};
//group values to find by its Type
var filter = values2find
.GroupBy(x=>x.Key)
.ToList();
//filter data
var result = tmp.AsEnumerable()
.Where(x=> filter.All(y=>y.Key==x.Field<string>("Type") && y.Any(z=>z.Value==x.Field<string>("Value"))))
.ToList();
Console.WriteLine($"Found {result.Count()} result(s)");
foreach(var f in result)
Console.WriteLine($"Type: {f.Field<string>("Type")}\tValue:{f.Field<string>("Value")}");
Результат:
Found 0 result(s)
Для получения более подробной информации, пожалуйста, смотрите:
Перечислимый.Все&ЛТ;метод&ГТ;(интерфейс IEnumerable&ЛТ;метод&ГТ;, функция&ЛТ;метод логического и GT;) Способ (Система.По LINQ) | Майкрософт Документы[
^]
Перечислимый.Любой Метод (System.Linq) | Microsoft Docs[
^]