【问题标题】:SQL splitting a column into 3 different columns with multiple seperatorsSQL 将一列拆分为具有多个分隔符的 3 个不同的列
【发布时间】:2016-12-09 12:26:48
【问题描述】:

我有下面的列,其中包含如图所示的数据

|DeliveryComment          |   
|-------------------------|    
|[1 * B018]               |  
|GARAGE                   |  
|BACK GARDEN. [124 * B002]|   
|[1 * B018]               |  
|                         |  
|[124 * B002]             |   
|[1 * B018]               |  
|                         |    
|[124 * B002]             |   

我想将此数据拆分为如下所示的三列。

|ColA       |ColB|ColC|  
|-----------|----|----|     
|           |1   |B018|   
|GARAGE     |    |    |   
|BACK GARDEN|124 |B002|  
|           |1   |B018|    
|           |    |    |    
|           |124 |B002|   
|           |1   |B018|  
|           |    |    |      
|           |124 |B002|

应该在 A 列中结束的数据最多可以包含 11 个字符。 应该在 B 列中结束的数据可以是最多 3 个字符的可变数值。 应该在 C 列结束的数据最多可以是 4 个字符。

数字周围总是有[],它们之间总是有*

【问题讨论】:

  • 似乎是一个足够简单的任务。到目前为止你尝试过什么?

标签: sql sql-server select substring


【解决方案1】:

创建并填充示例表(在您以后的问题中保存我们这一步)

DECLARE @t AS TABLE
(
    col  varchar(50) 
)

INSERT INTO @T VALUES
('[1 * B018]'),
('GARAGE'),
('BACK GARDEN. [124 * B002]'),
('[1 * B018]'),
(''),
('[124 * B002]'),
('[1 * B018]'),           
(''),
('[124 * B002]')

查询:

SELECT CASE WHEN charindex('[', col) > 0 THEN
           LEFT(col, charindex('[', col)-1)
       ELSE
           col
       END AS ColA,

       CASE WHEN charindex('[', col) = 0 THEN
           ''
       ELSE
           SUBSTRING(col, charindex('[', col) +1 ,charindex('*', col) - charindex('[', col) - 1)
       END AS ColB,

       CASE WHEN charindex('[', col) = 0 THEN
           ''
       ELSE
           SUBSTRING(col, charindex('*', col) +1 ,charindex(']', col) - charindex('*', col) - 1)
       END AS ColC
FROM @T

结果:

ColA            ColB    ColC
                1       B018
GARAGE      
BACK GARDEN.    124     B002
                1       B018

                124     B002
                1       B018

                124     B002

【讨论】:

  • 这很棒。应该提到这是一组数据样本,有什么方法可以按照您上面指出的方式将整个列中的数据提取到临时表中?如果没有,我可以将字段添加到临时表查询中。
  • 您可以使用select into #tmp 来填充临时表。
【解决方案2】:

此解决方案使用 CROSS APPLY 使 CHARINDEX 更易于管理。

SELECT
    LEFT(SUBSTRING(col,1,CASE WHEN a= 0 THEN LEN(col) ELSE a-1 END),11) AS [ColA]
    ,REPLACE(SUBSTRING(col,a+1,b-a),'*','') AS [ColB]
    ,REPLACE(SUBSTRING(col,b+1,c-b),']','') AS [ColC]
FROM
    @t 
        CROSS APPLY( SELECT CHARINDEX('[',Col,0)A
                            ,CHARINDEX('*',Col,0)B
                            ,CHARINDEX(']',Col,0)C
                            ) Z

注意:到目前为止,您的示例(包括这个示例)当前都有前导和尾随空格,需要使用 RTRIM 和 LTRIM 进行修剪。但现在他们会把代码弄得一团糟。

【讨论】:

    猜你喜欢
    • 2021-01-09
    • 2018-09-22
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多