表格规范化(将逗号分隔的字段解析为单个记录)

Fos*_*eng 5 sql t-sql sql-server database-design sql-server-2008

我有这样一张桌子:

设备

DeviceId   Parts

1          Part1, Part2, Part3
2          Part2, Part3, Part4
3          Part1
Run Code Online (Sandbox Code Playgroud)

我想创建一个表'Parts',将Parts栏中的数据导出到新表中.之后我将删除Parts列

预期结果

部分

PartId PartName

  1      Part1
  2      Part2
  3      Part3
  4      Part4
Run Code Online (Sandbox Code Playgroud)

DevicePart

DeviceId PartId

  1      1
  1      2
  1      3
  2      2
  2      3
  2      4
  3      1
Run Code Online (Sandbox Code Playgroud)

我可以在不使用游标的情况下在SQL Server 2008中执行此操作吗?

Ale*_*Aza 6

- 建立:

declare @Device table(DeviceId int primary key, Parts varchar(1000))
declare @Part table(PartId int identity(1,1) primary key, PartName varchar(100))
declare @DevicePart table(DeviceId int, PartId int)

insert @Device
values
    (1, 'Part1, Part2, Part3'),
    (2, 'Part2, Part3, Part4'),
    (3, 'Part1')
Run Code Online (Sandbox Code Playgroud)

- 脚本:

declare @DevicePartTemp table(DeviceId int, PartName varchar(100))

insert @DevicePartTemp
select DeviceId, ltrim(x.value('.', 'varchar(100)'))
from
(
    select DeviceId, cast('<x>' + replace(Parts, ',', '</x><x>') + '</x>' as xml) XmlColumn
    from @Device
)tt
cross apply
    XmlColumn.nodes('x') as Nodes(x)


insert @Part
select distinct PartName
from @DevicePartTemp

insert @DevicePart
select tmp.DeviceId, prt.PartId
from @DevicePartTemp tmp 
    join @Part prt on
        prt.PartName = tmp.PartName
Run Code Online (Sandbox Code Playgroud)

- 结果:

select *
from @Part

PartId      PartName
----------- ---------
1           Part1
2           Part2
3           Part3
4           Part4


select *
from @DevicePart

DeviceId    PartId
----------- -----------
1           1
1           2
1           3
2           2
2           3
2           4
3           1   
Run Code Online (Sandbox Code Playgroud)