Йог sh избили меня до этого; мое решение аналогично, но стоит отметить улучшение производительности ОГРОМНОЕ . Мы начнем с этого примера данных:
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#tickets','U') IS NOT NULL DROP TABLE #tickets;
CREATE TABLE #tickets (Id INT, [Name] VARCHAR(50), Label VARCHAR(1000));
INSERT #tickets (Id, [Name], Label)
VALUES
(1,'FirstTicket' , 'bike|motorbike'),
(2,'SecondTicket', 'bike'),
(3,'ThirdTicket' , 'e-bike|motorbike'),
(4,'FourthTicket', 'car|truck'),
(5,'FifthTicket', 'motorbike|bike');
Теперь оригинальная и значительно улучшенная версия:
-- Original
SELECT t.id, t.[Name], t.Label
FROM #tickets AS t
CROSS APPLY STRING_SPLIT(t.Label, '|') t1
WHERE t1.[value] IN ('bike', 'motorbike')
GROUP BY t.id, t.[Name], t.Label
HAVING COUNT(DISTINCT t1.[value]) = 2;
-- Improved Version Leveraging APPLY to avoid a sort
SELECT t.Id, t.[Name], t.Label
FROM #tickets AS t
CROSS APPLY
(
SELECT 1
FROM STRING_SPLIT(t.Label,'|') AS split
WHERE split.[value] IN ('bike','motorbike')
HAVING COUNT(*) = 2
) AS isMatch(TF);
Теперь планы выполнения:
Если сравнить затраты: версия без сортировки - запрос в 4,36 раза быстрее, чем оригинал. В действительности это больше, потому что в первой версии мы не просто сортируем, мы сортируем три столбца - int и два (n) varchar s. Поскольку затраты на сортировку равны N * LOG (N), исходный запрос становится экспоненциально медленнее, чем больше строк вы выбрасываете.