【问题标题】:How to separate string with delimiter into multiple columns?如何将带分隔符的字符串分成多列?
【发布时间】:2019-09-08 18:44:26
【问题描述】:

我想将单列数据分成多列。 我有一个名为 LocationCode 的列,它在表中的长度不同。

样本数据:

LocationCode (col name)

100.23432.356345.6765634.34324.5645.F
100.2343.565465.56756765756756.4535435345.76466.F
200.234324234.46565466456.678678678678.543545445.43243243.F
1502.23.5.56546.7657767575.567567.MGR

注意:将所有这些分成不同的列。 预期输出:

Column1   Column2   Column3     Column4      Column5    Column6    Column7
100       23432     356345      6765634       34324      5645         F
100       2343      565465   56756765756756  4535435345  76466        F
200    234324234  46565466456  678678678678  543545445  43243243      F
1502      23           5          56546     7657767575   567567      MGR

我的示例数据由分隔符分隔。并且整数值的长度不同。 新形成的列应该用分隔符分隔。

【问题讨论】:

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

您正在寻找PIVOT

SELECT [1] Col1,
       [2] Col2,
       [3] Col3,
       [4] Col4,
       [5] Col5,
       [6] Col6,
       [7] Col7
FROM
(
  VALUES
  ('100.23432.356345.6765634.34324.5645.F'),
  ('100.2343.565465.56756765756756.4535435345.76466.F'),
  ('200.234324234.46565466456.678678678678.543545445.43243243.F'),
  ('1502.23.5.56546.7657767575.567567.MGR')
) T(V)
CROSS APPLY
(
  SELECT Value VV,
         ROW_NUMBER() OVER(ORDER BY(SELECT 1)) RN
  FROM STRING_SPLIT(T.V, '.') --Use your own function since you have 2012 version
) TT(VV, RN)
PIVOT
(
  MAX(VV) FOR RN IN([1], [2], [3], [4], [5], [6], [7])
) TVP;

这将为您生成 7 列(仅 7 列),如果您有更多或更少,那么您可以使用动态 PIVOT。

Online Demo

【讨论】:

  • 第一个想法也是如此,但 OP 标记为 2012
  • 是的,你也提供了一个很好的例子@JohnCappelletti ;)
  • 来自String_Split:“输出行可能是任何顺序。顺序保证与输入字符串中子字符串的顺序匹配。”如果ROW_NUMBER() OVER(ORDER BY(SELECT 1)) 总是会生成相应的不可预测的顺序来匹配子字符串,我会感到惊讶。
【解决方案2】:

XML 方法可能更简洁,但这是一种分而治之的方法

with cte1 as 
(select col,charindex('.',col,charindex('.',col,(charindex('.',col)+1))+1) ind from table)

,cte2 as
(SELECT col, right(col,len(col)-ind) p1, left(col,ind-1) p2 from cte1)

select 
col,
parsename(p2,3) col1,
parsename(p2,2) col2,
parsename(p2,1) col3,
parsename(p1,4) col4,
parsename(p1,3) col5,
parsename(p1,2) col6,
parsename(p1,1) col7
from cte2;

Demo Fiddle

【讨论】:

    【解决方案3】:

    使用 cte 和条件聚合的另一种解决方法:

    with cte1(LocationCode, code, seqnum) as
    (
    select LocationCode, value as code,
        row_number() over(partition by LocationCode order by (select null)) as seqnum
    from location
    cross apply string_split(LocationCode, '.')
    )
    select LocationCode,
        max(case when seqnum = 1 then rtrim(code) end) as Column1,
        max(case when seqnum = 2 then rtrim(code) end) as Column2,
        max(case when seqnum = 3 then rtrim(code) end) as Column3,
        max(case when seqnum = 4 then rtrim(code) end) as Column4,
        max(case when seqnum = 5 then rtrim(code) end) as Column5,
        max(case when seqnum = 6 then rtrim(code) end) as Column6,
        max(case when seqnum = 7 then rtrim(code) end) as Column7
    from cte1
    group by LocationCode
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 2017-07-17
      • 2018-07-23
      • 2020-03-28
      • 2021-10-18
      • 2010-10-19
      相关资源
      最近更新 更多