Известно, что без ORDER BY требуемый порядок в выходном рекордсете вообще-то говоря не гарантирован. А в данном случае нужно именно гарантировать порядок строк, когда просто нет поля, по которому можно сделать ORDER BY. Есть следующее решение — ввести собственное фиктивное поле и делать ORDER BY по нему. Нам понадобится функция, которая парсит строку с перечислением идентификаторов (ID) и возвращает идентификаторы в виде набора данных:
IF OBJECT_ID (N'ParseIDList') IS NOT NULL
DROP FUNCTION [ParseIDList]
GO
CREATE FUNCTION [ParseIDList](@idList VARCHAR(MAX))
RETURNS @retList TABLE(N INT identity(1,1), ID INT)
AS
BEGIN
DECLARE @i INT, @j INT, @N INT, @val INT
SET @i = 0
SET @j = 1
SET @N = LEN(@idList)
WHILE @i < @N + 1 BEGIN
SET @i = CHARINDEX(',',@idList,@j)
IF @i = 0 SET @i = @N + 1
SET @val = SUBSTRING(@idList,@j,@i - @j)
INSERT INTO @retList ([ID]) VALUES (CONVERT(INT,@val))
SET @j = @i + 1
END
RETURN
END
GO
Затем, при запросе мы можем сделать JOIN
на результат, возвращаемый этой функцией:
SELECT
id
FROM some_table
join dbo.ParseIDList('1,3,2') p on p.ID = some_table.id
order by p.N