Tsql 试图操纵字符串,如if'26169;c785643',则结果应类似于“c785643”

Tsql 试图操纵字符串,如if'26169;c785643',则结果应类似于“c785643”,tsql,Tsql,我试图处理列中的字符串数据,例如给定的字符串是'20591;e123456;17507;c567890;15518;e135791'或'26169;c785643',然后 结果应该与“e123456”类似;c567890;e135791'或'c785643'。中间的位数可以是任意长度 到目前为止,我尝试过的一些方法是: 选择“替换”20591;e123456;17507;c567890;15518;e135791’,,; 这留给我的是20591年;e123456;17507;c567890;15

我试图处理列中的字符串数据,例如给定的字符串是'20591;e123456;17507;c567890;15518;e135791'或'26169;c785643',然后 结果应该与“e123456”类似;c567890;e135791'或'c785643'。中间的位数可以是任意长度

到目前为止,我尝试过的一些方法是:

选择“替换”20591;e123456;17507;c567890;15518;e135791’,,; 这留给我的是20591年;e123456;17507;c567890;15518;e135791',其中仍然包括前缀为“e”或“c”的数字。我想摆脱20591、17507和15518

创建将保持“%[[ec][0-9][;]%”模式的函数,并将除去其余的模式。
您没有包括您所在的SQL Server版本。如果您使用2016+可以使用SPLIT_字符串,否则a就可以了

针对单个变量:

靠着桌子:

返回:


最重要的建议是:不要在分隔字符串中存储任何数据。这违反了关系数据库概念1.NF的最基本原则

第二个提示非常相关:请始终使用适当的工具添加/标记您的问题。标记[tsql]指向SQL Server,但这可能是错误的,这将使两个答案都无效。请在完整产品上标记其版本,例如[sql-server-2012]。特别是使用字符串拆分时,不同版本之间有非常重要的与产品相关的更改

现在谈谈你的问题

使用几乎任何版本的SQL Server 我的建议使用了XML的技巧:

艾伦·伯斯坦的模型功劳

-询问

SELECT t.someid,t.somestring,A.CastedToXml
      ,STUFF(REPLACE(A.CastedToXml.query('/x[contains(text()[1],"#") and empty(substring(text()[1],2,100) cast as xs:int?)]')
                                  .value('.','nvarchar(max)'),'#',';'),1,1,'') TheNewList 
FROM @table t
CROSS APPLY(SELECT CAST('<x>' + REPLACE(t.somestring,';','</x><x>') + '</x>' AS XML)) A(CastedToXml);
在这里我使用;拆分字符串和数据以隐式连接值,空格分隔

v2017更新2 如果您有v2017+,我建议将JSON拆分器和字符串_AGG结合使用:


嗨,艾伦,在MS没有给STRING_SPLIT的结果添加位置之前,我会避免使用这个函数。。。对于v2016,我们拥有几乎同样快的JSON数组,它保证了给定的订单…谢谢@Alan。是否有一种不使用XML的解决方法。@HumbeBerginnings不是在v2017之前,它带来了字符串_AGG。任何其他方法都需要更笨拙的代码…感谢您的回复@Shnugo!我很抱歉,因为这是我的第一篇帖子,我会在将来记住这些要点。我使用的是SQL Server 2014。@YadneshBandekar没问题,欢迎您,我正在努力保持所有内容的一致性。我一直在为其他专栏文章使用字符操作函数,并希望为将来的工作人员保持一致:有没有不涉及XQuery的解决方案?[尽管如此,我必须说它工作得很好]。再次感谢!!:@HumbleBeginnings我可以理解您想要什么,但是:SQL Server在字符串操作方面不是很好。。。使用简单字符串函数拆分未定义长度的字符串将需要一个循环或递归CTE。在清理后重新连接碎片将再次需要相当难看的解决方法。您可以按照Alan Burstein的答案,将v2016附带的字符串分割函数替换为您将在那里找到的众多字符串分割函数之一。。。
NewString
----------------------
e123456,c567890,e135791

-- Against a table
DECLARE @table TABLE (someid INT IDENTITY, somestring VARCHAR(50));
INSERT @table VALUES ('20591;#e123456;#17507;#c567890;#15518;#e135791'),('26169;#c785643')

SELECT t.*, fn.NewString
FROM   @table AS t
CROSS APPLY 
(
  SELECT NewString = STUFF((
    SELECT      ','+split.item
    FROM        STRING_SPLIT(t.somestring,';') AS s
    CROSS APPLY (VALUES(REPLACE(s.[value],'#',''))) AS split(item)
    WHERE       split.item LIKE '[a-z][0-9]%'
    FOR XML PATH('')),1,1,'')
) AS fn;
someid      somestring                                         NewString
----------- -------------------------------------------------- -----------------------------
1           20591;#e123456;#17507;#c567890;#15518;#e135791     e123456,c567890,e135791
2           26169;#c785643                                     c785643
DECLARE @table TABLE (someid INT IDENTITY, somestring VARCHAR(50)); 
INSERT @table VALUES ('20591;#e123456;#17507;#c567890;#15518;#e135791'),('26169;#c785643')
SELECT t.someid,t.somestring,A.CastedToXml
      ,STUFF(REPLACE(A.CastedToXml.query('/x[contains(text()[1],"#") and empty(substring(text()[1],2,100) cast as xs:int?)]')
                                  .value('.','nvarchar(max)'),'#',';'),1,1,'') TheNewList 
FROM @table t
CROSS APPLY(SELECT CAST('<x>' + REPLACE(t.somestring,';','</x><x>') + '</x>' AS XML)) A(CastedToXml);
SELECT t.someid,t.somestring,A.CastedToXml
  ,REPLACE(A.CastedToXml.query('data(/x[empty(. cast as xs:int?)])')
                        .value('.','nvarchar(max)'),' ',';') TheNewList 
FROM @table t
CROSS APPLY(SELECT CAST('<x>' + REPLACE(t.somestring,';#','</x><x>') + '</x>' AS XML)) A(CastedToXml);
SELECT t.someid,STRING_AGG(A.[value],';') AS TheNewList
FROM @table t
CROSS APPLY OPENJSON(CONCAT('["',REPLACE(t.somestring,';#','","'),'"]')) A
WHERE TRY_CAST(A.[value] AS INT) IS NULL
GROUP BY t.someid;