MS SQL:从拆分字符串中选择并保留原始顺序

MS SQL:从拆分字符串中选择并保留原始顺序,sql,sql-server,Sql,Sql Server,我有一个简单的选择从一个分裂的查询 SELECT [id] FROM [user] WHERE [id] IN ( SELECT items FROM dbo.Split('8004, 7943, 2658, 6223, 7826', ',') ) 问题是,用户表上的select语句命令ID升序,但我希望保留ID在Split string函数中显示的原始顺序 这是我的拆分函数代码: ALTER FUNCTION [dbo].[Split](@String VARCHAR(8000),

我有一个简单的选择从一个分裂的查询

SELECT [id] 
FROM [user] WHERE [id] IN (
    SELECT items FROM dbo.Split('8004, 7943, 2658, 6223, 7826', ',')
)
问题是,用户表上的select语句命令ID升序,但我希望保留ID在Split string函数中显示的原始顺序

这是我的拆分函数代码:

ALTER FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1))       
RETURNS @temptable TABLE (items VARCHAR(8000))       
 AS       
 BEGIN       
 DECLARE @idx INT       
 DECLARE @slice VARCHAR(8000)       

 SELECT @idx = 1       
     IF len(@String)<1 OR @String IS NULL  RETURN       

 WHILE @idx!= 0       
 BEGIN       
     SET @idx = charindex(@Delimiter,@String)       
     IF @idx!=0       
         SET @slice = LEFT(@String,@idx - 1)       
     ELSE       
         SET @slice = @String       

     IF(LEN(@slice)>0)  
         INSERT INTO @temptable(Items) VALUES(@slice)       

     SET @String = RIGHT(@String,len(@String) - @idx)       
     IF LEN(@String) = 0 BREAK       
 END   
 RETURN       
 END
我需要的是:

8004
7943
2658
6223
7826
有什么办法可以做到这一点吗


谢谢

将函数重新写入为:

Create FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1))       
RETURNS @temptable TABLE (items VARCHAR(8000), rownum int)       
 AS       
 BEGIN       
 DECLARE @idx INT       
 DECLARE @slice VARCHAR(8000)       

 SELECT @idx = 1       
     IF len(@String)<1 OR @String IS NULL  RETURN       

 WHILE @idx!= 0       
 BEGIN       
     SET @idx = charindex(@Delimiter,@String)       
     IF @idx!=0       
         SET @slice = LEFT(@String,@idx - 1)       
     ELSE       
         SET @slice = @String       

     IF(LEN(@slice)>0)  
         INSERT INTO @temptable(Items) VALUES(@slice)       

     SET @String = RIGHT(@String,len(@String) - @idx)       
     IF LEN(@String) = 0 BREAK 

     --Added Rownumber here:
     ;With CTE as
     (
         Select Row_number() over (Order By (select 1)) as rownum
         ,Items
         FROM  @temptable
      )      
     Update T
     set T.rownum = CTE.rownum
     From @temptable T
     JOIN CTE ON T.Items = CTE.Items
 END   
 RETURN       
 END
 Go

选中此处。

只需从dbo.Split例程返回包含订单的附加字段(“例如N”)

N   Value
1   8004
2   7943
3   2658
函数可能看起来像

CREATE FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1))       
RETURNS @temptable TABLE (N int, items VARCHAR(8000))       
 AS       
 BEGIN       
 DECLARE @idx INT       
 DECLARE @slice VARCHAR(8000)
 DECLARE @N int SET @N = 1

 SELECT @idx = 1       
     IF len(@String)<1 OR @String IS NULL  RETURN       

 WHILE @idx!= 0       
 BEGIN       
     SET @idx = charindex(@Delimiter,@String)       
     IF @idx!=0       
         SET @slice = LEFT(@String,@idx - 1)       
     ELSE       
         SET @slice = @String       

     IF(LEN(@slice)>0) BEGIN  
         INSERT INTO @temptable(N, Items) VALUES(@N, @slice)       
         SET @N = @N + 1
     END

     SET @String = RIGHT(@String,len(@String) - @idx)       
     IF LEN(@String) = 0 BREAK       
 END   
 RETURN       
 END
 GO
然后将查询替换为

SELECT
    *
FROM
    [user]
    INNER JOIN dbo.Split() AS [split] ON ([user].[id] = [split].[items])
ORDER BY
    [split].[N] ASC

更改dbo.Split更好,因为它不会影响现有代码,但可以为您提供可重用的解决方案。

请发布dbo.Split函数的代码。我发现了问题:)在临时表中添加一个secSplit函数代码,您可以添加第二个表,并将@idx或其他“标识”放在那里变量,然后从函数返回按id排序的值。@sdrzymala问题不在于split函数,而是他使用“where”子句从用户表中提取数据。所以sql以不同的顺序将其取出,因为它使用自己的优化计划来完成
CREATE FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1))       
RETURNS @temptable TABLE (N int, items VARCHAR(8000))       
 AS       
 BEGIN       
 DECLARE @idx INT       
 DECLARE @slice VARCHAR(8000)
 DECLARE @N int SET @N = 1

 SELECT @idx = 1       
     IF len(@String)<1 OR @String IS NULL  RETURN       

 WHILE @idx!= 0       
 BEGIN       
     SET @idx = charindex(@Delimiter,@String)       
     IF @idx!=0       
         SET @slice = LEFT(@String,@idx - 1)       
     ELSE       
         SET @slice = @String       

     IF(LEN(@slice)>0) BEGIN  
         INSERT INTO @temptable(N, Items) VALUES(@N, @slice)       
         SET @N = @N + 1
     END

     SET @String = RIGHT(@String,len(@String) - @idx)       
     IF LEN(@String) = 0 BREAK       
 END   
 RETURN       
 END
 GO
CREATE FUNCTION dbo.Split (@String varchar(8000), @Delimiter char(1))
RETURNS TABLE
AS
RETURN (
    WITH Splitter AS (
      SELECT
        CHARINDEX(@Delimiter, @String) AS Pos,
        0 AS LastPos,
        1 AS N
      UNION ALL SELECT
        CHARINDEX(@Delimiter, @String, Pos + 1),
        Pos,
        N + 1
      FROM
        Splitter
      WHERE
        Pos > 0
    )
    SELECT
        N,
        LTRIM(RTRIM(SUBSTRING(@String, LastPos + 1, CASE WHEN Pos = 0 then 80000 ELSE Pos - LastPos - 1 END))) AS items
    FROM
        Splitter
  )
GO
SELECT
    *
FROM
    [user]
    INNER JOIN dbo.Split() AS [split] ON ([user].[id] = [split].[items])
ORDER BY
    [split].[N] ASC