如何在字符串sql中的某些字符后获取所有字符

时间:2017-09-20 20:38:37

标签: sql-server string tsql

我有一个包含以下格式字符串的行的列:

#S6TF3.01,#S6TF3.09,#S6TF3.10,#S6TF3.13

我希望能够为所有行获得以下结果:

01,09,10,13

我正在使用tsql并尝试过以下方法:

SUBSTRING(E.REJECT_WF_NOS, CHARINDEX('.', E.REJECT_WF_NOS) + 1, LEN(E.REJECT_WF_NOS)) 

4 个答案:

答案 0 :(得分:3)

我可能将这些分开,因为结构不是常数。你似乎只想要小数点后的值。这会将逗号上的值拆分,然后获取小数点后的所有内容,然后将其重新连接成一个字符串。

<强> ONLINE DEMO

declare @var varchar(64) = 'S6TF3.01,#S6TF3.09,#S6TF3.10,#S6TF3.13'

SELECT
    STUFF((
          SELECT ',' + substring(item,charindex('.',Item) + 1,32)
          FROM dbo.DelimitedSplit8K(@var,',')
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

<强> Here Is the Function from Jeff Moden

CREATE FUNCTION [dbo].[DelimitedSplit8K] (@pString VARCHAR(8000), @pDelimiter CHAR(1))
--WARNING!!! DO NOT USE MAX DATA-TYPES HERE!  IT WILL KILL PERFORMANCE!

RETURNS TABLE WITH SCHEMABINDING AS
RETURN

/* "Inline" CTE Driven "Tally Table" produces values from 1 up to 10,000...
enough to cover VARCHAR(8000)*/

  WITH E1(N) AS (
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
                ),                          --10E+1 or 10 rows
       E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
       E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
 cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
                     -- for both a performance gain and prevention of accidental "overruns"
                 SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
                ),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
                 SELECT 1 UNION ALL
                 SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
                ),
cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
                 SELECT s.N1,
                        ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                   FROM cteStart s
                )
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
        Item       = SUBSTRING(@pString, l.N1, l.L1)
   FROM cteLen l
;
GO

答案 1 :(得分:1)

如果您想要基于行的

,这是一个简单的2016版本
select reverse(substring(reverse(value),1,2)),* from 
string_split('#S6TF3.01,#S6TF3.09,#S6TF3.10,#S6TF3.13',',')

结果多行 - 2016年:

enter image description here **

如果您只想将它​​放在一行中,这可能是2016年的方式

DECLARE @MyTable TABLE
(
ID int ,
Strings varchar(10)
)

INSERT INTO @MyTable (ID,Strings)
select 1,reverse(substring(reverse(value),1,2)) as SplittedValues
from string_split('#S6TF3.01,#S6TF3.09,#S6TF3.10,#S6TF3.13',',')

---Select * from @MyTable

SELECT ID, NewVales = STUFF((SELECT N', ' + Strings 
FROM @MyTable AS p2
WHERE p2.ID = p.ID 
ORDER BY Strings
FOR XML PATH(N'')), 1, 2, N'')
FROM @MyTable AS p
GROUP BY ID
ORDER BY ID;

结果1行 - 2016

enter image description here

答案 2 :(得分:0)

为此你甚至不需要分离器;你可以使用parsename来“拆分”这些值。

declare @string varchar(100) = '#S6TF3.01,#S6TF3.09,#S6TF3.10,#S6TF3.13';

select newString = stuff
(( select ','+substring(item, 1, charindex(',', item)-1)
   from (values (4),(3),(2),(1)) t(n)
   cross apply (values (substring(@string, charindex('.',@string)+1, 8000)+',')) s(string)
   cross apply (values (parsename(string,n))) split(item)
   for xml path('')), 1,1,'');

这将比delimitedsplit8k更快,并且不需要SQL Server 2016.在SQL Server 2017上,您可以进一步简化:

select string_agg(substring(item, 1, charindex(',', item)-1),',')
from (values (4),(3),(2),(1)) t(n)
cross apply (values (substring(@string, charindex('.',@string)+1, 8000)+',')) s(string)
cross apply (values (parsename(string,n))) split(item)

答案 3 :(得分:0)

如果您有一行一行的数据,如下表结构:

ID  DATA
1   #S6TF3.01
2   #S6TF3.09
3   #S6TF3.10
4   #S6TF3.13

如果您总是有如上所述的数据,那么只需编写子串函数,如下所示:

SELECT SUBSTRING(DATA, 8, 2) DATA from #TEMP

结果:

ID  DATA       Result
1   #S6TF3.01   01
2   #S6TF3.09   09
3   #S6TF3.10   10
4   #S6TF3.13   13