T-SQL:将字符串分成多个列

时间:2016-12-01 23:51:47

标签: sql sql-server tsql sql-server-2012

实施例

Column 1:
| word1 word2 word3 word4 |

 Col 1:  Col 2:  Col 3:  Col 4:
| word1 | word2 | word3 | word |

是否可以将不同的单词或短语从字符串分成多列?字符串中的所有单词和短语通常用双空格分隔,没有别的。是否有我可以使用的预定义函数,如CAST或INTERSECT,或者我必须自己编写?

4 个答案:

答案 0 :(得分:2)

借助CROSS APPLY和一些XML。易于扩展和/或签约

Declare @YourTable table (id int,Column1 varchar(max))
Insert Into @YourTable values
(1,'word1 word2 word3 word4'),
(2,'some other words')

Select A.ID
      ,B.*
 From  @YourTable A
 Cross Apply (
        Select Pos1 = xDim.value('/x[1]','varchar(max)')
              ,Pos2 = xDim.value('/x[2]','varchar(max)')
              ,Pos3 = xDim.value('/x[3]','varchar(max)')
              ,Pos4 = xDim.value('/x[4]','varchar(max)')
              ,Pos5 = xDim.value('/x[5]','varchar(max)')
              ,Pos6 = xDim.value('/x[6]','varchar(max)')
              ,Pos7 = xDim.value('/x[7]','varchar(max)')
              ,Pos8 = xDim.value('/x[8]','varchar(max)')
              ,Pos9 = xDim.value('/x[9]','varchar(max)')
         From (Select Cast('<x>' + Replace(A.Column1,' ','</x><x>')+'</x>' as XML) as xDim) A
       ) B

返回

enter image description here

答案 1 :(得分:2)

这是一个动态的sql版本。约翰的,如果你不知道最大字数。完成所需操作的关键技术是拆分字符串和数据透视(或条件聚合)。因为你有同时做两件事,约翰的方法是一个很好的捷径。

{ Ben Z, B000333 }

答案 2 :(得分:0)

如果您的字数不是固定的数字,您可以使用动态脚本,这是一个示例:

IF OBJECT_ID('tempdb..#tb') IS NOT NULL DROP TABLE #tb
CREATE TABLE #tb (id int,Column1 varchar(max))
insert Into #tb values
(1,'word1 word2 word3 word'),
(2,'w1 w2 w3 w4 w5 w6')

DECLARE  @Cols NVARCHAR(max),@sql nvarchar(MAX)
DECLARE @MaxWordCount INT 
SELECT @MaxWordCount=MAX(LEN(t.Column1)-len(replace(t.Column1,' ',''))+1) from #tb as t
    SELECT @Cols=ISNULL(@Cols+',','')+'[Col '+LTRIM(sv.number)+']' FROM master.dbo.spt_values as sv WHERE  sv.Type='P' and sv.number BETWEEN 1 AND @MaxWordCount

PRINT @Cols
SET @sql='SELECT * from (
             SELECT t.*, w.* FROM #tb AS t
             CROSS APPLY (VALUES (convert(XML, ''<n>'' + replace(t.Column1, '' '', ''</n><n>'') + ''</n>''))) x(c)
             CROSS APPLY (SELECT ''Col '' + ltrim(row_number()OVER (ORDER BY getdate()))  AS col
                                 ,s.b.value(''.'', ''varchar(200)'') AS wd
                          FROM x.c.nodes(''n'') s(b)) w
         ) a PIVOT (max(wd) for col in ('+@Cols+')) p'
PRINT @sql
EXEC(@sql)
IF OBJECT_ID('tempdb..#tb') IS NOT NULL DROP TABLE #tb
id  Column1 Col 1   Col 2   Col 3   Col 4   Col 5   Col 6
2   w1 w2 w3 w4 w5 w6   w1  w2  w3  w4  w5  w6
1   word1 word2 word3 word  word1   word2   word3   word    NULL    NULL

答案 3 :(得分:0)

这个怎么样?

Create Table AllData (Column0 varchar(500))
Insert Into AllData Values ('word1 word2 word3 word4')
Select parsename(replace(replace(replace([Column0],'  ',' '),'  ',' '),' ','.'), 4) [Col1],
parsename(replace(replace(replace([Column0],'  ',' '),'  ',' '),' ','.'), 3) [Col2],
parsename(replace(replace(replace([Column0],'  ',' '),'  ',' '),' ','.'), 2)  [Col3],  
parsename(replace(replace(replace([Column0],'  ',' '),'  ',' '),' ','.'), 1)   [Col4]

from AllData