开发者社区> 问答> 正文

T-SQL通过变量定界符分割包含字母和数字字符的字符串

我正在尝试拆分具有3个设置的Alpha字符的字符串,该字符串可以按任何顺序显示,后跟一个数字值。我遇到的问题是字母字符的顺序不固定。字母字符后面的数字值的数量也不是,它可以包含以下任何示例:

X1Y45Z1 Y25Z1 X1Y9Z1 X2Z6 在本地IT部门的大量帮助下(我仍在学习SQL),我设法将XY和Z分成单独的列,并在其后加上数字,但它们并不总是按顺序出现

Col1可能包含X或Y Col2可能包含Y或Z Col3可能包含Z或不包含Z 我正在尝试获得如下结果:

如果X在col1中,则在新列“ X”中显示X后面的编号,如果Y在col1中,则在新列“ Y”中显示Y后面的编号,等等。

目前,我们使用2个cte分解字符串。并且我正在尝试简化它,以便我可以搜索字符串,在创建“ X”,“ Y”,“ Z”之后具有3列,并在每个Alpha分隔符后放入正确的数字。我应该注意,我没有完全的管理员访问权限,所以我无法创建新表或更新/插入数据或清理它。

如果格式略有不正确,也深感抱歉。这是我在StackOverflow上的第一篇文章

declare @tbl table
(
    Col1 varchar(100), <-------This Column contains the values I want
)

insert into @tbl
    select Col1,
    from table1, 
    where xyz

;with cte as
(
    select
        Col1,
        replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(**Col1**,'P', '</x><x>P'),'C', '</x><x>C'),'I', '</x><x>I'),'M', '</x><x>M'),'S', '</x><x>S'),'Q', '</x><x>Q'),'L', '</x><x>L'),'T', '</x><x>T'),'E', '</x><x>E'),'R', '</x><x>R'),'U', '</x><x>U'),'W', '</x><x>W')
 **Col1NODES**
    from 
        @tbl
)
, cte2 (Col1, Col1Nodes) as
(
    select
        Col1,
        convert(xml,'<z><x>' + Col1nodes + '</x></z>') **Col1NODES**
    from 
        cte
)
select 
    Col1, 
    isnull(Col1Nodes.value('/z[1]/x[2]','varchar(100)'),'-') F1,
    isnull(Col1Nodes.value('/z[1]/x[3]','varchar(100)'),'-') F2,
    isnull(Col1Nodes.value('/z[1]/x[4]','varchar(100)'),'-') F3
from 
    cte2

展开
收起
祖安文状元 2020-01-04 15:52:15 578 0
1 条回答
写回答
取消 提交回答
  • 如果您拥有SQL Server 2016+,则可以尝试基于JSON使用以下解决方案。重要的部分是将输入数据转换为有效的JSON对象(例如,X1Y45Z1转换{"X":1,"Y":45,"Z":1}为)。之后,您需要OPENJSON()使用适当的WITH子句使用功能解析此对象,以在输出中定义列。

    表:

    CREATE TABLE Data (
       TextData nvarchar(100)
    )
    INSERT INTO Data
       (TextData)
    VALUES
       ('X1Y45Z1'),
       ('Y25Z1'),
       ('X1Y9Z1'),
       ('X2Z6'),
       ('Z1X6')
    
    

    声明:

    SELECT d.TextData, j.*
    FROM Data d
    CROSS APPLY OPENJSON(
       CONCAT(
          N'{',
          STUFF(REPLACE(REPLACE(REPLACE(d.TextData, N'X', N',"X":'), N'Y', N',"Y":'), N'Z', N',"Z":'), 1, 1, N''),
          N'}'
       )   
    ) WITH (
       X int '$.X',
       Y int '$.Y',
       Z int '$.Z'
    ) j
    
    

    输出:

    ---------------------
    TextData    X   Y   Z
    ---------------------
    X1Y45Z1     1   45  1
    Y25Z1           25  1
    X1Y9Z1      1   9   1
    X2Z6        2       6
    Z1X6        6       1
    
    

    对于SQL Server 2016之前的版本,您可以使用基于XML的方法。您需要将文本数据转换为适当的XML(例如,X1Y45Z1转换 X 1 Y 45 Z 1 为):

    SELECT
       TextData,
       XmlData.value('(/row[name = "X"]/value/text())[1]', 'nvarchar(4)') AS X,
       XmlData.value('(/row[name = "Y"]/value/text())[1]', 'nvarchar(4)') AS Y,
       XmlData.value('(/row[name = "Z"]/value/text())[1]', 'nvarchar(4)') AS Z
    FROM (
       SELECT
          TextData, 
          CONVERT(
             xml, 
          CONCAT(
               STUFF(REPLACE(REPLACE(REPLACE(d.TextData, N'X', N'</value></row><row><name>X</name><value>'), N'Y', N'</value></row><row><name>Y</name><value>'), N'Z', N'</value></row><row><name>Z</name><value>'), 1, 14, N''),
               N'</value></row>'
             )
          ) AS XmlData
       FROM Data d
    ) x
    
    2020-01-04 15:52:50
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server在电子商务中的应用与实践 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载