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