SQL-将逗号分隔的字符串变成单独的行后更新表

时间:2019-01-25 12:10:40

标签: sql sql-server

样本数据

CREATE TABLE Testdata
(
 SomeID INT,
 OtherID INT,
 String VARCHAR(MAX)
)
INSERT Testdata SELECT 1,  9, '18,20,22'
INSERT Testdata SELECT 2,  8, '17,19'
INSERT Testdata SELECT 3,  7, '13,19,20'
INSERT Testdata SELECT 4,  6, ''
INSERT Testdata SELECT 9, 11, '1,2,3,4'

我设法使用下面的查询删除逗号

Select A.SomeID
,B.*
From [filter].[dbo].[Testdata] A
Cross Apply (
Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From  (Select x = Cast('<x>' + replace((Select 
replace(A.String,',','§§Split§§')
as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) 
as A 

Cross Apply x.nodes('x') AS B(i)
) B

现在,我希望的是如何使用新的一组值更新现有表。 谢谢。

2 个答案:

答案 0 :(得分:2)

因此,由于(在您的评论中)您说要创建一个新表,该表可以与现有查询非常简单

SQL Server 2016之前的版本

CREATE TABLE NewData
(
  SomeID INT,
  String VARCHAR(MAX)
)

INSERT INTO NewData
SELECT A.SomeID,
       B.*
FROM [dbo].[Testdata] A
Cross Apply (
Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From  (Select x = Cast('<x>' + replace((Select 
replace(A.String,',','§§Split§§')
as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) 
as A 
Cross Apply x.nodes('x') AS B(i)
) B

SELECT * FROM NewData

发布SQL Server 2016

您现在可以使用STRING_SPLIT来摆脱大型SQL块

CREATE TABLE NewData2
(
  SomeID INT,
  String VARCHAR(MAX)
)

INSERT INTO NewData2
SELECT A.SomeID,
       S.value
FROM [dbo].[Testdata] A
CROSS APPLY STRING_SPLIT (A.String, ',') S

SELECT * FROM NewData2

您将没有任何限制等,因此您需要像往常一样将它们放入CREATE TABLE中。

注意:您应该真正更改表定义,以便现在存储整数而不是varchar。

答案 1 :(得分:2)

CREATE TABLE Testdata
    (
     SomeID INT,
     OtherID INT,
     String VARCHAR(MAX)
    )
    INSERT Testdata SELECT 1,  9, '18,20,22'
    INSERT Testdata SELECT 2,  8, '17,19'
    INSERT Testdata SELECT 3,  7, '13,19,20'
    INSERT Testdata SELECT 4,  6, ''
    INSERT Testdata SELECT 9, 11, '1,2,3,4'

    CREATE TABLE NewData
    (
      SomeID INT,
      otherID int,
      String VARCHAR(MAX)
    )

    INSERT INTO  NewData (SomeID,OtherID,String)


    Select A.SomeID,OtherID,
    B.* 
    From [dbo].[Testdata] A
    Cross Apply (
    Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>' + replace((Select 
    replace(A.String,',','§§Split§§')
    as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) 
    as A 

    Cross Apply x.nodes('x') AS B(i)
    ) B


    Delete  from Testdata
    Insert Testdata (SomeID, OtherID , String)

    select SomeID, OtherID , String from NewData
相关问题