【问题标题】:Splitting delimited values in a SQL column into multiple rows that uses multiple delimiters将 SQL 列中的分隔值拆分为使用多个分隔符的多行
【发布时间】:2012-12-17 20:46:27
【问题描述】:

我正在寻找一些帮助来拆分在 sql 函数/语句中使用多个分隔符的字段。我遵循了一些已经列出的示例HERE

这里可以很好地使用单个分隔符。但是,我需要拆分基于以下内容的字段。它的格式是 qty x itemno description、qty x itemno description 等。因此我需要将第一个“x”第二个空格“”和最后一个逗号上的语句分开。我想我可以根据正则表达式语句,但不确定如何去做..

有人可以帮忙吗?

    OnSameLine = substring( ( SELECT ', ' + 
                 coalesce (CAST(CNT.qty AS varchar(1000)), '') +                  
                 ' x ' + '['+ coalesce (CNT.Itemno,'') + ']' + 
                 ' ' + coalesce (STK.Desc#1,'')

我需要的格式..

PK qty itemno description
PK qty itemno description 

等等。

【问题讨论】:

    标签: sql sql-server sql-server-2005


    【解决方案1】:

    试试这个:

    基于here的文章

    ;with T(id, Cols) as
    (
      select 1, '10 x 1234 description1,11 x 456 description2' 
      UNION ALL
      select 2, '40 x 123478 description3,51 x 45678 description4' 
    ),
    --first split all comma separated into different rows
    CTE2 AS 
    (
        SELECT id, 
        CAST(N'<H><r>' + replace(Replace(Vals.a.value('.', 'NVARCHAR(50)'),
            ' ','|'), '|', '</r><r>') + '</r></H>' as XML) Cols
        FROM
        (
        SELECT *,CAST (N'<H><r>' + Replace(cols,',','</r><r>') + 
            '</r></H>' AS XML) AS [vals]
        FROM T) d
        CROSS APPLY d.[vals].nodes('/H/r') Vals(a)
    )
    -- split all ' ' demilited values now
    SELECT distinct id, Vals.a.value('(/H/r)[1]', 'VARCHAR(100)') AS Qty,
    Vals.a.value('(/H/r)[2]', 'VARCHAR(100)') AS X,
    Vals.a.value('(/H/r)[3]', 'VARCHAR(100)') AS ItemNo,
    Vals.a.value('(/H/r)[4]', 'VARCHAR(100)') AS Description
    FROM
    (
    SELECT *
    FROM CTE2) d
    CROSS APPLY d.[cols].nodes('/H/r') Vals(a)
    

    【讨论】:

    • +1 按空格分割成不同的列。我不确定这是否是要求。我在第一次拆分后交换了QtyX。结帐我的。
    • 谢谢,我刚刚尝试过,但忘记了我在该字段中有一些不符合指示格式的旧历史数据.. 抱歉,我进行了 XML 解析:第 1 行,字符 54,非法名称字符.如果格式不正确,有没有办法返回原始字段。否则这看起来正是我需要的
    • 我隔离了一个有效的数据集,它的工作栏是空白的 qty 列,因此所有列都向右移动一个。我认为是这条线导致了错误.. Vals.a.value('(/H/r)[1]', 'VARCHAR(100)') AS Qty,
    【解决方案2】:

    如果你只是想分割,交换Qty和PK,试试这个;

    DECLARE @S VARCHAR(max)= 'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'
    
    DECLARE @X XML
    SELECT @X  = '<myxml><n><d>' + 
                 REPLACE (@S,',','</d></n><n><d>') + '</d></n></myxml>'
    
    
    SELECT SUBSTRING(x,firstSpace,secondSpace-firstSpace) + ' ' + 
           SUBSTRING(x,1,firstSpace) + ' ' + 
           SUBSTRING(x,secondSpace,len(x))
    FROM ( --Getting CharIndex of first and second spaces
        SELECT x, CHARINDEX(' ',x,1) firstSpace, CHARINDEX(' ',x,CHARINDEX(' ',x,1)+1) secondSpace
        FROM ( --Spliting by "," into records 
            SELECT C.value('d[1]','VARCHAR(50)') x
            FROM @X.nodes('/myxml/n') Cols (C) ) T1
    ) T2
    

    SQL Fiddle here

    --Data
    'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'
    
    --Results
    'PK1 Q1 ITM1 D1'
    'PK2 Q2 ITM2 D2'
    

    如果你想将它们分成几列,那么试试这个;

    DECLARE @S VARCHAR(500)= 'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'
    DECLARE @X XML
    
    SELECT @X  = '<myxml><n><d>' + 
    REPLACE(REPLACE (@S,',','</d></n><n><d>'), ' ', '</d><d>') + 
    '</d></n></myxml>'
    
    
    SELECT  C.value('d[2]','VARCHAR(50)') PK,
            C.value('d[1]','VARCHAR(50)') Qty,
            C.value('d[3]','VARCHAR(50)') Item,
            C.value('d[4]','VARCHAR(50)') Description
            FROM @X.nodes('/myxml/n') Cols (C)
    

    SQL Fiddle here

    --Data 
    'Q1 PK1 ITM1 D1,Q2 PK2 ITM2 D2'
    
    --Results
    PK1 | Q1 | ITM1 | D1
    PK2 | Q2 | ITM2 | D2
    

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 2018-11-02
      • 2022-11-17
      相关资源
      最近更新 更多