Как создать `Union` на основе списка строк через запятую - PullRequest
0 голосов
/ 22 марта 2019

Предположим, я создаю хранимую процедуру в моем SQL Server для таблицы my_table.

Целью этой хранимой процедуры является получение входного ключевого параметра @keyword nvarchar(255) и разделенной запятыми строки '@vehicleList nvarchar (266)'.

@catList в основном содержит значения того, какие флажки фильтров были проверены на переднем конце (варианты: автомобиль, грузовик, мотоцикл).Таким образом, список транспортных средств может выглядеть следующим образом:

@vehicleList = "car, truck, motorcycle" 

или это

"car, motorcycle" 

или это

"truck" 

Эти имена флажков совпадают с именами столбцов вmy_table.Я хочу вернуть определенные столбцы из my_table, основываясь на том, что мой параметр @keyword находится в одном из столбцов, но ТОЛЬКО если этот столбец находится в @vehicleList.

Если бы @vehicleList всегда был 'Car, Truck, Motorcyle', я мог бы сделать это:

SELECT ID, T_Number, Car, Truck, Motorcycle, Date
FROM T_Ticket
WHERE Car Like '%' + @Keyword + '%'
UNION ALL
SELECT ID, T_Number, Car, Truck, Motorcycle, Date 
FROM T_Ticket
WHERE Truck Like '%' + @Keyword + '%'
UNION ALL
SELECT ID, T_Number, Car, Truck, Motorcycle, Date 
FROM T_Ticket
WHERE Motorcycle Like '%' + @Keyword + '%'

Мой вопрос, как бы я сделал это, основываясь на переменной, запятойразделенная строка, которая будет отличаться при каждом вызове хранимой процедуры?

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

Спускаясь по динамическому маршруту SQL, вы можете сделать:

DECLARE @vehicleList nvarchar(266);
DECLARE @keyword nvarchar(255);

DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ID, T_Number, Car, Truck, Motorcycle, Date' + NCHAR(10) + NCHAR(13) +
           N'FROM T_Ticket' + NCHAR(10) + NCHAR(13) +
           N'WHERE ' + 
           STUFF((SELECT NCHAR(10) + NCHAR(13) +
                         N'   OR ' + QUOTENAME([value]) + N' LIKE N''%'' + @Keyword + N''%'''
                  FROM STRING_SPLIT(@vehicleList,',')
                  FOR XML PATH(N''),TYPE).value(N'.','nvarchar(MAX)'),1,8,N'') + N';';
--PRINT @SQL; --Your debugging best friend
EXEC sp_executesql @SQL, N'@keyword nvarchar(255)', @keyword = @keyword;
2 голосов
/ 22 марта 2019

в одну сторону будет UNPIVOT, как показано ниже.

В отличие от UNION ALL, в случае совпадения нескольких столбцов он не будет возвращать дубликаты, но я все равно сомневаюсь, что вы этого хотите (если вы используете JOIN вместо EXISTS).

SELECT *
FROM   T_Ticket
WHERE  EXISTS (SELECT *
               FROM   (VALUES ('Car', Car),
                              ('Truck', Truck),
                              ('Motorcycle', Motorcycle) ) V(colname, colvalue)
                      JOIN STRING_SPLIT(@vehicleList, ',') vl
                        ON ltrim(vl.value) = colname
               WHERE  colvalue LIKE '%' + @Keyword + '%') 
0 голосов
/ 24 марта 2019

Я думаю, что это самый простой способ достичь того, что вам нужно

SELECT ID, T_Number, Car, Truck, Motorcycle, Date
FROM T_Ticket
WHERE (@vehicleList LIKE '%car%' AND Car LIKE '%' + @Keyword + '%')
OR    (@vehicleList LIKE '%truck%' AND Truck LIKE '%' + @Keyword + '%')
OR    (@vehicleList LIKE '%motorcycle%' AND Motorcycle LIKE '%' + @Keyword + '%')
...