Прошу прощения, но принятый в настоящее время ответ (от саами) неверен.
Проблема с этим ответом состоит в том, что он использует ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
, чтобы получить порядок элементов в строке с разделителями-запятыми, но поскольку order by
делается на select null
, на самом деле происходит то, что row_number
назначит числа в произвольном порядке - который может совпадать или не совпадать с порядком строк в исходной строке.
Для получения дополнительной информации, прочитайте Без ремня безопасности Конора Каннингема - Ожидание заказа без ORDER BY.
Если ваш разделенный UDF возвращает таблицу с двумя столбцами, где один содержит подстроку, а другой содержит ее индекс, например, DelimitedSplit8K Джеффа Модена, тогда просто используйте ItemNumber
(или эквивалентный) столбец для order by
. Если он возвращает только один столбец, содержащий подстроки, вы можете использовать этот приятный трюк, который я узнал из Аарона Бертранда. Решение старых проблем с новыми функциями SQL Server STRING_AGG и STRING_SPLIT - это гарантирует возврат правильных порядок подстрок, если они уникальны.
Простое изменение в ответе Сами даст вам правильные результаты, если подстроки уникальны в строке с разделителями-запятыми - вместо ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
используйте CHARINDEX(',' + Value + ',', ',' + @Ids + ',')
, которая будет возвращать индекс каждой подстроки внутри запятой с разделителями. строка:
CREATE TABLE T(
ID INT,
SomeValue VARCHAR(45)
);
INSERT INTO T VALUES
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four'),
(5, 'Five');
DECLARE @IDs VARCHAR(200) = '3,5,2';
SELECT T.*
FROM T
INNER JOIN
(SELECT Value,
CHARINDEX(',' + Value + ',', ',' + @Ids + ',') AS Seq
FROM dbo.Split(@Ids, ',')
) TT
ON T.ID = TT.Value
ORDER BY TT.Seq;