简体   繁体   English

使用SQL Server通过定界符在列中拆分字符串

[英]Split string in columns by delimiter using SQL Server

I need to split my one column value in column using delimiter, below is the table structure. 我需要使用定界符在列中拆分我的一列值,以下是表结构。

create table #a
(
    id int, 
    timeline varchar(100)
)

insert into #a
values (1, 'Semi Annual Q2 (May/June/July) & Q4 (Nov/Dec/Jan)'),
       (2, 'Semi Annual Q1 (Feb/Mar/Apr) & Q3 (Aug/Sep/Oct)'),
       (3, 'Annual Q3 (Aug/Sep/Oct)'),
       (4, 'Annual Q2 (May/June/July)'),
       (5, 'Annual Q4 (Nov/Dec/Jan)'),
       (6, 'Semi Annual Q1 (Jan/Feb/Mar) & Q3 (July/Aug/Sep)')

select * from #a

Output I want to split timeline values by ' / ' delimiter and make separate column for separate month and all month should be in sequence, which look like a below sample. 输出我想用'/'分隔符分割时间轴值,并为单独的月份创建单独的列,并且所有月份都应按顺序排列,看起来像下面的示例。

ID  M1   M2    M3    M4    M5    M6
---------------------------------------
1   May  June  July  Nov   Dec   Jan
2   Feb  Mar   Apr   Aug   Sep   Oct
3   Aug  Sep   Oct   NULL  NULL  NULL
4   May  June  July  NULL  NULL  NULL
5   Nov  Dec   Jan   NULL  NULL  NULL
6   Jan  Feb   Mar   July  Aug   Sep

So far, I have tried this: 到目前为止,我已经尝试过了:

select
    timeline,
    substring((substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline) - 1)), 1, charindex('/', substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline) - 1)) - 1) as M1,
    replace(replace(right(substring(substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline)), 1, charindex(')', substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline)))), charindex('/', reverse(substring(substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline)), 1, charindex(')', substring(timeline, CHARINDEX('(', timeline) + 1, len(timeline))))), 4)), '/', ''), ')', '') as M3
from 
    #a;

which is not a code and too tedious also. 这不是代码,也太繁琐了。 please help if you have efficient way to do this. 如果您有有效的方法,请提供帮助。

The SplitCSVToTable8K function being used in the following solution, is the same DelimitedSplit8K function mentioned above... 以下解决方案中使用的SplitCSVToTable8K函数与上面提到的DelimitedSplit8K函数相同...

Here's how to use it in the solution: 以下是在解决方案中使用它的方法:

WITH 
    cte_ParseTimeline AS (
        SELECT 
            a.id,
            rn = ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY sc.ItemNumber),
            sc.Item
        FROM 
            #a a
            CROSS APPLY dbo.SplitCSVToTable8K(REPLACE(REPLACE(a.timeline, '(', '/'), ')', '/'), '/') sc
        WHERE 
            sc.Item LIKE ('[A-Z][a-z][a-z]')
            OR 
            sc.Item LIKE ('[A-Z][a-z][a-z][a-z]')
        )
SELECT 
    pt.id,
    M1 = MAX(CASE WHEN pt.rn = 1 THEN pt.Item END),
    M2 = MAX(CASE WHEN pt.rn = 2 THEN pt.Item END),
    M3 = MAX(CASE WHEN pt.rn = 3 THEN pt.Item END),
    M4 = MAX(CASE WHEN pt.rn = 4 THEN pt.Item END),
    M5 = MAX(CASE WHEN pt.rn = 5 THEN pt.Item END),
    M6 = MAX(CASE WHEN pt.rn = 6 THEN pt.Item END)
FROM 
    cte_ParseTimeline pt
GROUP BY
    pt.id;

Results... 结果...

id          M1    M2    M3    M4    M5    M6
----------- ----- ----- ----- ----- ----- -----
1           May   June  July  Nov   Dec   Jan
2           Feb   Mar   Apr   Aug   Sep   Oct
3           Aug   Sep   Oct   NULL  NULL  NULL
4           May   June  July  NULL  NULL  NULL
5           Nov   Dec   Jan   NULL  NULL  NULL
6           Jan   Feb   Mar   July  Aug   Sep

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM