T-SQL 不太适合处理逗号分隔值。但是,通过创造性地使用Recursive CTE,可以不费吹灰之力地拆分列。以下查询假设原始数据中连续的类型总数不超过 8 个 - 可以轻松扩展它以处理任意数量的类型(尽管不是动态的,但必须知道最大数量):
;with TypesSplit as (
select [ID], [SN], 1 as [Index],
case when CHARINDEX(',', [Types]) <> 0 then substring([Types], CHARINDEX(',', [Types])+1, 1000) else '' end as [Types],
case when CHARINDEX(',', [Types]) <> 0 then substring([Types], 1, CHARINDEX(',', [Types])-1) else [Types] end as [Type]
from Types
union all
select [ID], [SN], [Index] + 1 as [Index],
case when CHARINDEX(',', [Types]) <> 0 then substring([Types], CHARINDEX(',', [Types])+1, 1000) else '' end as [Types],
case when CHARINDEX(',', [Types]) <> 0 then substring([Types], 1, CHARINDEX(',', [Types])-1) else [Types] end as [Type]
from TypesSplit
where LEN([Types])>0
)
select [ID],[SN],
max(case when [Index]=1 then [Type] end) as Types1,
max(case when [Index]=2 then [Type] end) as Types2,
max(case when [Index]=3 then [Type] end) as Types3,
max(case when [Index]=4 then [Type] end) as Types4,
max(case when [Index]=5 then [Type] end) as Types5,
max(case when [Index]=6 then [Type] end) as Types6,
max(case when [Index]=7 then [Type] end) as Types7,
max(case when [Index]=8 then [Type] end) as Types8
from TypesSplit
group by [ID],[SN]
(演示:http ://www.sqlfiddle.com/#!6/c522f/9 )
基本思想是使用CHARINDEX找到每个逗号的位置,然后SUBSTRING从头开始拆分每个类型。递归循环遍历所有类型,直到没有可用的类型。这些类型通过[Index]
列编号,以允许在输出中以相同的顺序复制它们。输出基本上是递归 CTE 生成的行数据的透视表,在透视之前看起来像这样:
| ID | SN | INDEX | TYPES | TYPE |
|----|-----|-------|------------------------------|------|
| 1 | 123 | 1 | XYZ,TEST,RJK,CDF,TTT,UMB,UVX | ABC |
| 2 | 234 | 1 | CDF,TTT,UMB,UVX,TTT,UMB,UVX | RJK |
| 3 | 345 | 1 | XYZ,TTT,UMB,UVX,TTT,UMB,UVX | OID |
| 3 | 345 | 2 | TTT,UMB,UVX,TTT,UMB,UVX | XYZ |
| 3 | 345 | 3 | UMB,UVX,TTT,UMB,UVX | TTT |
| 3 | 345 | 4 | UVX,TTT,UMB,UVX | UMB |
| 3 | 345 | 5 | TTT,UMB,UVX | UVX |
| 3 | 345 | 6 | UMB,UVX | TTT |
| 3 | 345 | 7 | UVX | UMB |
| 3 | 345 | 8 | | UVX |
| 2 | 234 | 2 | TTT,UMB,UVX,TTT,UMB,UVX | CDF |
| 2 | 234 | 3 | UMB,UVX,TTT,UMB,UVX | TTT |
| 2 | 234 | 4 | UVX,TTT,UMB,UVX | UMB |
| 2 | 234 | 5 | TTT,UMB,UVX | UVX |
| 2 | 234 | 6 | UMB,UVX | TTT |
| 2 | 234 | 7 | UVX | UMB |
| 2 | 234 | 8 | | UVX |
| 1 | 123 | 2 | TEST,RJK,CDF,TTT,UMB,UVX | XYZ |
| 1 | 123 | 3 | RJK,CDF,TTT,UMB,UVX | TEST |
| 1 | 123 | 4 | CDF,TTT,UMB,UVX | RJK |
| 1 | 123 | 5 | TTT,UMB,UVX | CDF |
| 1 | 123 | 6 | UMB,UVX | TTT |
| 1 | 123 | 7 | UVX | UMB |
| 1 | 123 | 8 | | UVX |
旋转后,最终输出如下所示:
| ID | SN | TYPES1 | TYPES2 | TYPES3 | TYPES4 | TYPES5 | TYPES6 | TYPES7 | TYPES8 |
|----|-----|--------|--------|--------|--------|--------|--------|--------|--------|
| 1 | 123 | ABC | XYZ | TEST | RJK | CDF | TTT | UMB | UVX |
| 2 | 234 | RJK | CDF | TTT | UMB | UVX | TTT | UMB | UVX |
| 3 | 345 | OID | XYZ | TTT | UMB | UVX | TTT | UMB | UVX |