我需要在select语句中拆分字符串并插入表

时间:2011-05-13 17:03:30

标签: sql tsql

我在一张表中有数据。我需要将它复制到另一个表。其中一列是文本分隔的字符串。所以我正在考虑选择所有列插入get indentity值,并使用子查询基于分隔符进行拆分并将其插入另一个表。

这是数据示例

ID     Name     City       Items
1      Michael  Miami      item|item2|item3|item4|item5
2      Jorge    Hallandale item|item2|item3|item4|item5

名称城市复制到一个表获取标识 并将拆分并复制到另一个具有标识列值

的表中

所以输出应该是

用户表

UserID Name     City
1      Michael  Miami
2      Jorge    Hallandale

...

Items table

ItemID   UserID   Name
1        1        Item
2        1        Item2
3        1        Item3
4        1        Item4
5        2        Item
6        2        Item2
7        2        Item3
8        2        Item4

不确定如何使用T-SQL。有例子的答案将不胜感激

4 个答案:

答案 0 :(得分:6)

您可以创建自定义函数以在T-Sql中拆分字符串。然后,您可以将Split函数作为JOIN的一部分与基表一起使用,以生成INSERT语句的最终结果。看看这个post。希望这有帮助。

答案 1 :(得分:3)

您可以使用xml并交叉应用。

请参阅以下内容:

DECLARE @t table (ID int, Name varchar(20), City varchar(20), Items varchar(max));
INSERT @t 
SELECT 1,'Michael','Miami'     ,'item|item2|item3|item4|item5' UNION
SELECT 2,'Jorge'  ,'Hallandale','item|item2|item3|item4|item5'

DECLARE @u table (UserID int identity(1,1), Name varchar(20), City varchar(20));
INSERT @u (Name, City)
SELECT DISTINCT Name, City FROM @t 

DECLARE @i table (ItemID int identity(1,1), UserID int, Name varchar(20));

WITH cte_Items (Name, Items) as (
   SELECT 
        Name 
       ,CAST(REPLACE('<r><i>' + Items + '</i></r>','|','</i><i>') as xml) as Items 
   FROM 
       @t 
   )

INSERT @i (UserID, Name)
SELECT 
     u.UserID
    ,s.Name as Name
FROM
    cte_Items t 
    CROSS APPLY (SELECT i.value('.','varchar(20)') as Name FROM t.Items.nodes('//r/i') as x(i) ) s
    INNER JOIN @u u ON t.Name = u.Name 


SELECT * FROM @i 

在此处查看更多信息: http://www.kodyaz.com/articles/t-sql-convert-split-delimeted-string-as-rows-using-xml.aspx

答案 2 :(得分:1)

你能用递归完成这个吗?我的T-SQL很生疏,但这可能会帮助您找到正确的方向:

WITH CteList AS (
   SELECT 0 AS ItemId
        , 0 AS DelimPos
        , 0 AS Item_Num
        , CAST('' AS VARCHAR(100)) AS Item
        , Items AS Remainder
   FROM Table1
   UNION ALL
   SELECT Row_Number() OVER(ORDER BY UserID) AS ItemId
        , UserID
        , CASE WHEN CHARINDEX('|', Remainder) > 0
               THEN CHARINDXEX('|', Remainder)
               ELSE LEN(Remainder)
          END AS dpos
        , Item_num + 1 as Item_Num
        , REPLACE(Remainder, '|', '') AS Element
        , right(Remainder, dpos+1) AS Remainder
    FROM CteList
    WHERE dpos > 0
      AND ItemNum < 20 /* Force a MAX depth for recursion */
)
SELECT ItemId
     , Item
FROM CteList
WHERE item_num > 0
ORDER BY ItemID, Item_Num

答案 3 :(得分:1)

对于这个问题,请参阅:How to split cell content and extract information into a new column in an SQL select statement?。它与您的需求非常相似,但您必须稍微修改它,可能使用OUTPUT语句来捕获进程中的身份。