我从Split查询中选择了这个简单的。
SELECT [id]
FROM [user] WHERE [id] IN (
SELECT items FROM dbo.Split('8004, 7943, 2658, 6223, 7826', ',')
)
问题是,用户表上的select语句命令ID递增,但我想保留ID在Split字符串函数中出现的原始顺序。
这是我的分割功能代码:
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
所以,我目前得到的结果是:
2658
6223
7826
7943
8004
我需要的是:
8004
7943
2658
6223
7826
有关如何实现这一目标的任何想法?
谢谢!
答案 0 :(得分:0)
将函数重写为:
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
然后查询为:
SELECT U.[id]
FROM [test_user] U
Join (SELECT items,rownum FROM dbo.Split('8004, 7943, 2658, 6223, 7826', ','))
as T on T.items = U.id
order by T.rownum asc
点击此处Demo。
答案 1 :(得分:0)
只需从包含订单的dbo.Split例程返回附加字段(&#34; N&#34;例如)
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
或者您可能希望用CTE版本替换拆分例程:
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
更改dbo.Split更好,因为它不会影响现有代码,但会为您提供可重复使用的解决方案。