Ответ 1
Ваша первая необходимость разделить переменную, которую вы проверяете на строки, и удалить дубликаты. Для всего лишь нескольких символов вы можете просто использовать конструктор с табличной оценкой:
DECLARE @b varchar(5) = 'DCA';
SELECT DISTINCT Letter = SUBSTRING(@b, n.Number, 1)
FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS n (Number)
WHERE n.Number <= LEN(@b)
Что дает:
Letter
----------
D
C
A
Теперь вы можете сравнить это с вашим столбцом и ограничить его только столбцами, в которых столбец содержит все буквы (сделанные в предложении HAVING
)
DECLARE @b varchar(5) = 'DCA';
WITH Letters AS
( SELECT DISTINCT Letter = SUBSTRING(@b, n.Number, 1)
FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS n (Number)
WHERE n.Number <= LEN(@b)
)
SELECT *
FROM (VALUES ('AA'), ('ABCD'), ('ABCDEFG'), ('CAB'), ('NA')) AS t (Col)
WHERE EXISTS
( SELECT 1
FROM Letters AS l
WHERE t.Col LIKE '%' + l.Letter + '%'
HAVING COUNT(DISTINCT l.Letter) = (SELECT COUNT(*) FROM Letters)
);
Если ваша переменная может быть длиннее 10 символов, вам может потребоваться немного другой метод разделения строк. Я бы по-прежнему использовал числа, чтобы сделать это, но вместо этого использовал бы Ицик Бен-Ган уложил метод CTE:
WITH N1 AS (SELECT N FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2)
SELECT ROW_NUMBER() OVER(ORDER BY N)
FROM N3;
Это даст вам набор чисел от 1 до 10000, и вы можете просто добавить больше CTE и кросс-соединений, если это необходимо для расширения процесса. Таким образом, с более длинной строкой вы можете:
DECLARE @b varchar(5) = 'DCAFGHIJKLMNEOPNFEDACCRADFAE';
WITH N1 AS (SELECT N FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Numbers (Number) AS (SELECT TOP (LEN(@b)) ROW_NUMBER() OVER(ORDER BY N) FROM N3),
Letters AS (SELECT DISTINCT Letter = SUBSTRING(@b, n.Number, 1) FROM Numbers AS n)
SELECT *
FROM (VALUES ('ABCDDCAFGHIJKLMNEOPNFEDACCRADFAEEFG'), ('CAB'), ('NA')) AS t (Col)
WHERE EXISTS
( SELECT 1
FROM Letters AS l
WHERE t.Col LIKE '%' + l.Letter + '%'
HAVING COUNT(DISTINCT l.Letter) = (SELECT COUNT(*) FROM Letters)
);