Sql 将多个字段上的字符串拆分为一个结果
我有一个表,看起来像下面设置为一个值的字段:Sql 将多个字段上的字符串拆分为一个结果,sql,sql-server,Sql,Sql Server,我有一个表,看起来像下面设置为一个值的字段: |---------------------|------------------|------------------| | Colour | Amount | Size | |---------------------|------------------|------------------| | Black,Blue,Green | 1,2,2
|---------------------|------------------|------------------|
| Colour | Amount | Size |
|---------------------|------------------|------------------|
| Black,Blue,Green | 1,2,2 | 100,100,100 |
|---------------------|------------------|------------------|
我需要对每个字符串进行拆分,然后一次性返回
我现在有了这个,它适用于颜色:
SELECT value as colour
FROM [table_name]
CROSS APPLY STRING_SPLIT(colour, ',')
我不知道如何一次拆分多个字符串。它应按如下方式返回:
|---------------------|------------------|------------------|
| Colour | Amount | Size |
|---------------------|------------------|------------------|
| Black | 1 | 100 |
|---------------------|------------------|------------------|
| Blue | 2 | 100 |
|---------------------|------------------|------------------|
| Green | 2 | 100 |
|---------------------|------------------|------------------|
任何帮助都会很好 不幸的是,string_split没有提供保留其生成的子字符串顺序的选项。因此,在这种情况下,这是非常非常棘手的
我更喜欢递归CTE,直到函数得到修复:
with cte as (
select convert(varchar(max), null) as color,
convert(varchar(max), null) as amount,
convert(varchar(max), null) as size,
convert(varchar(max), colors + ',') as rest_colors,
convert(varchar(max), amounts + ',') as rest_amounts ,
convert(varchar(max), sizes + ',') as rest_sizes,
0 as lev
from t
union all
select left(rest_colors, charindex(',', rest_colors) - 1),
left(rest_amounts, charindex(',', rest_amounts) - 1),
left(rest_sizes, charindex(',', rest_sizes) - 1),
stuff(rest_colors, 1, charindex(',', rest_colors), ''),
stuff(rest_amounts, 1, charindex(',', rest_amounts), ''),
stuff(rest_sizes, 1, charindex(',', rest_sizes), ''),
lev + 1
from cte
where rest_colors <> ''
)
select color, amount, size
from cte
where lev > 0;
是一个dbfiddle。正如Gordon提到的,string_split不包含GTD序列。也就是说,如果您对表值函数开放,请考虑下面的步骤,在这里我们解压缩您的数据,然后应用最终的枢轴。注:RN=。。。如果您有自己的ID,可以用自己的ID替换
我调整了这些值,以说明存在正确的排序
范例
返回
如果感兴趣的话,函数
你真的需要在这里修改你的设计。然而,STRING_SPLIT不知道顺序位置是什么。我建议找一个DSPLIT8K_铅。
;with cte as (
Select RN = row_number() over (order by (select null))
,[Colour]
,[Amount]
,[Size]
From YourTable
)
Select *
From (
Select RN,Item='Colour',B.* From cte Cross Apply [dbo].[tvf-Str-Parse](Colour,',') B
Union All
Select RN,Item='Amount',B.* From cte Cross Apply [dbo].[tvf-Str-Parse](Amount,',') B
Union All
Select RN,Item='Size' ,B.* From cte Cross Apply [dbo].[tvf-Str-Parse](Size ,',') B
) src
Pivot ( max(RetVal) for Item in ([Colour],[Amount],[Size] ) ) pvt
RN RetSeq Colour Amount Size
1 1 Black 1 100
1 2 Blue 2 200
1 3 Green 3 300
CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);