如何从特定起始位置返回字符串中的所有其他字符?
示例:从位置1开始
1050231
结果:
1521
从第2位开始
1050231
结果:
003
答案 0 :(得分:3)
使用数字表通常是避免SQL中循环的最佳方法。 如果您还没有数字表,那么您应该阅读Jeff Moden的The "Numbers" or "Tally" Table: What it is and how it replaces a loop。
要创建数字表,您可以使用以下脚本:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
既然您有一个数字表,您可以使用它来从字符串中选择特定的字符,如下所示:
DECLARE @s varchar(20) = '1050231',
@Start int = 1
SELECT Substring(@s, Number, 1)
FROM Numbers
WHERE Number >= @Start
AND (Number - @Start) % 2 = 0
AND Number <= DATALENGTH(@s)
答案 1 :(得分:2)
一种方法使用递归CTE:
with cte as (
select @pos as pos, @str as str
union all
select pos + 2, str
from cte
where pos + 2 <= len(@str)
)
select substring(str, pos, 1)
from cte;
这是rextester。
答案 2 :(得分:2)
迟到的答案,但这是另一种选择
示例强>
Declare @S varchar(max) = '1050231'
Declare @P int =1
Select NewValue = (Select substring(substring(@S,@P,len(@S)),N,1)
From (Select Top (len(@S)-@P+1) N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1) A
Where N%2=1
For XML Path('')
)
<强>返回强>
NewValue
1521
答案 3 :(得分:1)
丑陋的方式 - 一段时间的循环,因为戈登给出了递归的CTE方法。
declare @string varchar(64) = 1050231
declare @start int = 1
declare @result varchar(64) = ''
set @result = @result + substring(@string,@start,1)
while @start < len(@string)
begin
set @start = @start + 2
select @result = @result + substring(@string,@start,1)
end
select @result
答案 4 :(得分:0)
您可以使用STUFF
:
declare @i VARCHAR(20) = '1050231';
select @i = IIF(LEN(@i) >= sub.s, STUFF(@i,sub.s,1,''),@i)
FROM(SELECT 1 s UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) sub;
-- any tally table
SELECT @i;
-- 003
declare @i VARCHAR(20) = '1050231';
select @i = IIF(LEN(@i) > sub.s, STUFF(@i,sub.s+1,1,''),@i)
FROM(SELECT 1 s UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) sub;
SELECT @i;
-- 1521
<强> DBFiddle Demo 强>