Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将多个字段上的字符串拆分为一个结果_Sql_Sql Server - Fatal编程技术网

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)
);