如何将值拆分成多行?

时间:2013-12-11 13:05:32

标签: sql-server-2008

我有一张这样的表

     keytype   keyvalue
----------------------------
     type1     st1,st2,st3
--------------------------------
      type2    ts1,ts2,ts3

我想将数据插入到像

这样的临时表中
    type1   type2
------------------------
    st1     ts1
-----------------
    st2     ts2
--------------------
    st3     ts3

我该怎么办。请告诉我。谢谢

1 个答案:

答案 0 :(得分:2)

您应该以关系方式存储此数据,而不是将多个数据存储在CSV字符串中。如果您无法修复设计,那么这是一种方法,但它做了几个假设:(a)您只需要两种类型(b)类型具有相同数量的逗号分隔值。如果有超过两行的话,扩展并不是非常繁琐,但除非你想要恢复到真正乏味的动态SQL,否则你需要事先了解它们的数量。

首先,创建一个有序的分割函数:

CREATE FUNCTION [dbo].[SplitStrings_Ordered]
(
    @List       NVARCHAR(MAX),
    @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN (SELECT [Index] = ROW_NUMBER() OVER (ORDER BY Number), Item 
    FROM (SELECT Number, Item = SUBSTRING(@List, Number, 
      CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)
     FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
      FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2) AS n(Number)
      WHERE Number <= CONVERT(INT, LEN(@List))
      AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
    ) AS y);
GO

然后,假设你有一个这样的表:

DECLARE @x TABLE(keytype VARCHAR(32), keyvalue VARCHAR(MAX));

INSERT @x VALUES('type1','st1,st2,st3'),('type2','ts1,ts2,ts3');

您可以将两个使用CROSS APPLY的CTE加入源表:

;WITH t1 AS 
(
  SELECT s.[Index], s.Item FROM @x AS x 
  CROSS APPLY dbo.SplitStrings_Ordered(x.keyvalue, ',') AS s 
  WHERE x.keytype = 'type1'
), t2 AS 
(
  SELECT s.[Index], s.Item FROM @x AS x 
  CROSS APPLY dbo.SplitStrings_Ordered(x.keyvalue, ',') AS s 
  WHERE x.keytype = 'type2'
)
-- INSERT #some_temp_table(columns)
SELECT type1 = t1.Item, type2 = t2.Item 
  FROM t1 INNER JOIN t2 ON t1.[Index] = t2.[Index]
  ORDER BY t1.[Index];