Sql server 使用SQL Server按分隔符拆分列中的字符串
我需要使用分隔符在列中拆分我的一列值,下面是表结构Sql server 使用SQL Server按分隔符拆分列中的字符串,sql-server,string,delimiter,Sql Server,String,Delimiter,我需要使用分隔符在列中拆分我的一列值,下面是表结构 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, 'A
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
输出我想按“/”分隔符分割时间线值,并为单独的月份创建单独的列,所有月份应按顺序排列,如下示例所示
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
到目前为止,我已经尝试过:
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;
这不是一个代码,也太乏味了。如果您有有效的方法执行此操作,请提供帮助。以下解决方案中使用的SplitCSVToTable8K函数与上面提到的DelimitedSplit8K函数相同 以下是如何在解决方案中使用它:
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;
结果
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
Jeff Moden的DelimitedSplit8K函数应该可以做到这一点。。。你可以在这里找到它。。。我也推荐杰夫的拆分器。但更重要的是,我建议停止存储分隔数据的做法。它违反了1NF,造成了很多痛苦。可能是@Jayank的重复-感谢您的反馈。我很高兴我能来。:)