将split_string中的行转换为

时间:2017-09-15 02:59:09

标签: sql tsql sql-server-2016

我试图将一组行转置到表格​​中。在我的存储过程中,我将分隔字符串作为输入,并需要转置它。

SELECT * 
FROM string_split('123,4,1,0,0,5|324,2,0,0,0,4','|')
CROSS APPLY  string_split(value,',')

我从中收到:

value           value
123,4,1,0,0,5   123
123,4,1,0,0,5   4
123,4,1,0,0,5   1
123,4,1,0,0,5   0
123,4,1,0,0,5   0
123,4,1,0,0,5   5
324,2,0,0,0,4   324
324,2,0,0,0,4   2
324,2,0,0,0,4   0
324,2,0,0,0,4   0
324,2,0,0,0,4   0
324,2,0,0,0,4   4

|分隔的值是客户详细信息。在每个客户端中,有六个属性,由,分隔。我想要一个输出表:

ClientId ClientTypeId AttrA AttrB AttrC AttrD
------------------------------------------------
123      4            0     0     0     5
324      2            0     0     0     4

最好的方法是什么?我一直在关注PIVOT,但无法使其发挥作用,因为我似乎需要行号,至少。

2 个答案:

答案 0 :(得分:0)

这个答案假设行号功能将“遵循字符串的顺序”。如果不是,则需要在结果表中编写自己的包含行号的拆分。 (这是在官方文档页面上询问的,但没有给出正式答案)。

SELECT
  MAX(CASE WHEN col = 1 THEN item ELSE null END) as ClientId,
  MAX(CASE WHEN col = 2 THEN item ELSE null END) as ClientTypeId,
  MAX(CASE WHEN col = 3 THEN item ELSE null END) as AttrA,
  MAX(CASE WHEN col = 4 THEN item ELSE null END) as AttrB,
  MAX(CASE WHEN col = 5 THEN item ELSE null END) as AttrC,
  MAX(CASE WHEN col = 6 THEN item ELSE null END) as AttrD
FROM (
  SELECT A.value as org, B.value as item, 
         ROW_NUMBER() OVER (partition by A.value) as col 
  FROM string_split('123,4,1,0,0,5|324,2,0,0,0,4','|') as A
  CROSS APPLY  string_split(A.value,',') as B
) X
GROUP BY org

您可能会在聚合函数中忽略有关空值的消息。 (我总是忘记哪些平台关心,哪些不关心。)如果这样做,可以用0替换null。

  

注意,这并不是那么快并且使用CTE在CHARINDEX中查找字符串中的5个逗号然后使用SUBSTRING来提取值。但是我懒得写出那个我需要测试的解决方案才能完全解决1个问题。不过,如果你有一个大数据集,我建议你这样做。

答案 1 :(得分:0)

我知道你已经得到了很多答案,但在这里你可以找到一个PIVOT解决方案

select [ClientID],[ClientTypeId],[AttrA],[AttrB],[AttrC],[AttrD]
FROM 
(
select case when ColumnRow = 1 then 'ClientID'
        when ColumnRow = 2 then 'ClientTypeId'
        when ColumnRow = 3 then 'AttrA'
        when ColumnRow = 4 then 'AttrB'
        when ColumnRow = 5 then 'AttrC'
        when ColumnRow = 6 then 'AttrD'   else null end as 
 ColumnRow,t.value,ColumnID from (

 select ColumnID,z.value as stringsplit,b.value,  cast(Row_number() 
 over(partition by z.value order by z.value) as 
 varchar(50)) as ColumnRow from (SELECT cast(Row_number() over(order by 
 a.value) as 
 varchar(50)) as ColumnID,
 a.value

 FROM string_split('123,4,1,0,0,5|324,2,0,0,0,4','|') a
 )z  
 CROSS APPLY  string_split(value,',') b
 )t

 ) AS SOURCETABLE
 PIVOT
 (
 MAX(value)
 FOR ColumnRow IN ([ClientID],[ClientTypeId],[AttrA],[AttrB],[AttrC],
 [AttrD])
 )
 AS
 PivotTable