T-SQL从字符串返回每个其他字符

时间:2018-04-23 19:08:19

标签: sql-server tsql

如何从特定起始位置返回字符串中的所有其他字符?

示例:从位置1开始

1050231

结果:

1521

从第2位开始

1050231

结果:

003

5 个答案:

答案 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