sql将字符串拆分为一行

时间:2012-10-12 08:00:36

标签: sql sql-server string sql-server-2008

declare @sqlstr varchar(max);
select @sqlstr = 'a,b,c,d,e,f';

我想在sql server2008中使用sql语句到一行有六列。

a,b,c,d,e,f

3 个答案:

答案 0 :(得分:4)

如果您可以将其声明为nvarchar(MAX)而不是varchar(max),则可以尝试将其转换为动态sql。例如:

declare @sqlstr nvarchar(max); 
--Select the initial values
select @sqlstr = 'a,b,c,d,e,f';
--Replace the comma so the string becomes a','b','c','d','e','f
select @sqlstr = REPLACE(@sqlstr, ',', ''',''')
--Add select to the beginning and add leading and trailing ' around the select values
select @sqlstr = 'Select ''' + @sqlstr + ''''
--execute the dynamic sql of select 'a','b','c','d','e','f'
exec sp_executesql @sqlstr

也可以稍微消除

declare @sqlstr nvarchar(max); 
--Select the initial values
select @sqlstr = 'a,b,c,d,e,f';
--Build the sql statement
select @sqlstr = 'Select ''' + REPLACE(@sqlstr, ',', ''',''') + ''''
--execute the dynamic sql of select 'a','b','c','d','e','f'
exec sp_executesql @sqlstr

或者如果你被绑定到VARCHAR(MAX)

DECLARE @sqlstr VARCHAR(MAX)
--Select the initial values
SELECT @sqlstr = 'a,b,c,d,e,f';
--Build the sql statement
DECLARE @DynamicSQL NVARCHAR(MAX) = 'Select ''' + REPLACE(@sqlstr, ',', ''',''') + ''''
--execute the dynamic sql of select 'a','b','c','d','e','f'
EXEC sp_executesql @DynamicSQL

请参阅Sql Fiddle示例

答案 1 :(得分:0)

试试这个:

declare @str varchar(10)='a,b,c,d,e,f'

;WITH cte AS (
         SELECT CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[1]').value('.','varchar(max)') col1,
                CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[2]').value('.','varchar(max)') col2,
                CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[3]').value('.','varchar(max)') col3,
                CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[4]').value('.','varchar(max)') col4,
                CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[5]').value('.','varchar(max)') col5,
                CAST('<r>'+REPLACE(@str,',','</r><r>')+'</r>' AS XML).query('/r[6]').value('.','varchar(max)') col6


)
SELECT   
        CASE WHEN col1 = '' THEN NULL ELSE col1 END col1,
        CASE WHEN col2 = '' THEN NULL ELSE col2 END col2,
        CASE WHEN col3 = '' THEN NULL ELSE col3 END col3,
        CASE WHEN col4 = '' THEN NULL ELSE col4 END col4,
        CASE WHEN col5 = '' THEN NULL ELSE col5 END col5,
        CASE WHEN col6 = '' THEN NULL ELSE col6 END col6
FROM    cte

答案 2 :(得分:0)

我使用CTE和PIVOT的变种:

declare @sqlstr varchar(max);
select @sqlstr = 'a,b,c,d,e,f';
WITH cte AS 
 (
  SELECT 1 as pos, REPLACE(@sqlstr, ',', '') as sqlstr
  UNION ALL
  SELECT pos + 1 as pos, sqlstr
  FROM cte WHERE pos + 0 < LEN(sqlstr)
  )
SELECT *
FROM 
 (
  SELECT pos, SUBSTRING(sqlstr, pos, 1) AS sqlstr
  FROM cte
 ) x
PIVOT
(
 MAX(sqlstr)
 FOR pos IN ([1], [2], [3], [4], [5], [6])
) p

动态PIVOT的变体:

declare @sqlstr varchar(max);
select @sqlstr = 'a,b,c,d,e,f,g,t'; 
DECLARE @cols AS nvarchar(max),
        @query AS nvarchar(max)

IF OBJECT_ID('tempdb.dbo.#sqlstrTable') IS NOT NULL DROP TABLE dbo.#sqlstrTable
CREATE TABLE dbo.#sqlstrTable (pos int, sqlstr nvarchar(max))

;WITH cte AS 
 (
  SELECT 1 as pos, REPLACE(@sqlstr, ',', '') as sqlstr
  UNION ALL
  SELECT pos + 1 as pos, sqlstr
  FROM cte WHERE pos + 0 < LEN(sqlstr)
  )
INSERT dbo.#sqlstrTable
SELECT * FROM cte

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(pos)
FROM dbo.#sqlstrTable FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')

SET @query = '
SELECT ' + @cols + '
FROM
 (
  SELECT pos, SUBSTRING(sqlstr, pos, 1) AS sqlstr
  FROM dbo.#sqlstrTable
  ) x
PIVOT
 (
  MAX(sqlstr)
  FOR pos IN (' + @cols + ')
  ) p'

EXECUTE(@query)