我有一张这样的表:
设备
DeviceId Parts
1 Part1, Part2, Part3
2 Part2, Part3, Part4
3 Part1
我想创建一个表'Parts',将Parts栏中的数据导出到新表中。我会在那之后删除Parts列
预期结果
零件
PartId PartName
1 Part1
2 Part2
3 Part3
4 Part4
DevicePart
DeviceId PartId
1 1
1 2
1 3
2 2
2 3
2 4
3 1
我可以在不使用游标的情况下在SQL Server 2008中执行此操作吗?
答案 0 :(得分: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')
- 脚本:
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
- 结果:
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
答案 1 :(得分:1)
您需要一个Tally表才能在没有游标的情况下完成此操作。
按照说明在此处创建计数表:Tally Tables by Jeff Moden
此脚本会将表放入Temp数据库,因此您可能希望更改“使用DB”语句
然后,您可以运行下面的脚本,将设备和部件的细分插入到临时表中。然后,您应该能够通过部件名称加入零件表(以获取ID)并插入到新的DevicePart表中。
select *,
--substring(d.parts, 1, t.n)
substring(d.parts, t.n, charindex(', ', d.parts + ', ',t.n) - t.n) 'Part'
into #devicesparts
from device d
cross join tally t
where t.n < (select max(len(parts))+ 1 from device)
and substring(', ' + d.parts, t.n, 1) = ', '
答案 2 :(得分:0)
查看使用fn_Split从逗号分隔值创建表变量。 然后,您可以使用它来驱动插入。
编辑:实际上,我认为你可能仍然需要一个游标。将这个答案留给fn_Split会有所帮助。答案 3 :(得分:0)
如果每个设备有最大数量的部件,那么是的,可以在没有光标的情况下完成,但这非常复杂。
实质上,创建一个表(或视图或子查询),其中包含PartID字符串中每个可能索引的DeviceID和一个PartID列。这可以通过使用fn_split或您选择的其他方法使PartID列计算列来实现。从那里你做了这个表的多个自我UNION,在每个PartID列的自UNION中有一个表。 self-UNION中的每个表只有一个PartID列包含在表的查询的选择列表中。