I've tried flexing my Google-fu to no avail so here I am! Unfortunately I cannot change anything about these tables as they are coming out of an application that I have to report out of.
In SQL Server 2008, I'm trying to replace multiple values in one text string column (Table 1) with the value from another table (Table 2).
Thanks in advance!!
Table 1
id value
-------------
1 a1, a2, a3
2 a2, a3
3 a4
Table 2
id value
---------
a1 Value1
a2 Value2
a3 Value3
a4 Value4
Desired Output
id value
-----------------------------
1 Value1, Value2, Value3
2 Value2, Value3
3 Value4
This site has a delimited text split function http://www.sqlservercentral.com/articles/Tally+Table/72993/
Use that function to split your values out into a temp table. Replace the values in your temp table with the new values. Then use STUFF..FOR XML
to combine the records back together and update your table.
One query with a few cte's should be able to handle all of this after you add the function to your database.
Example using Sql Fiddle
Using the DelimitedSplit8K found at http://www.sqlservercentral.com/articles/Tally+Table/72993/ as suggested by @user1221684 you might come up with something like this. Working with delimited data like this is a pain. First you have to parse the string so you can join it to the other table and then ruin by stuffing it back into a denormalized form.
Make sure that if you use this that you understand that function and what this code is doing. This is not entry level t-sql and it will be YOU supporting this at 3am when it breaks in production, not me.
if OBJECT_ID('tempdb..#table1') is not null
drop table #table1;
create table #table1
(
id int,
value varchar(50)
);
insert #table1
select 1, 'a1, a2, a3' union all
select 2, 'a2, a3' union all
select 3, 'a4';
if OBJECT_ID('tempdb..#table2') is not null
drop table #table2;
create table #table2
(
id varchar(50),
value varchar(50)
);
insert #table2
select 'a1', 'Value1' union all
select 'a2', 'Value2' union all
select 'a3', 'Value3' union all
select 'a4', 'Value4';
with parsedValues as
(
select t1.id
, t1.value
, LTRIM(x.item) as item
from #table1 t1
cross apply dbo.DelimitedSplit8K(t1.value, ',') x
)
, swappedVals as
(
select pv.id
, t2.value
from parsedValues pv
join #table2 t2 on t2.id = pv.item
)
select id
, STUFF((select ',' + value
from swappedVals sv2
where sv2.id = sv.id
order by sv2.value --need to make sure to order here so the results are in the right order
for XML path('')), 1, 1, '') as MyValues
from swappedVals sv
group by id
;
I'm sorry for this solution in advance :) It does what you need though:
create table TableA(
id int,
string varchar(255)
)
create table table2(
id varchar , text varchar(255)
)
insert into tableA values(1,'a,b,c,d')
insert into tableA values(2,'e,f')
insert into table2 values('a', 'value1')
insert into table2 values('b', 'value2')
insert into table2 values('c', 'value3')
insert into table2 values('d', 'value4')
insert into table2 values('e', 'value5')
insert into table2 values('f', 'value6')
select id, left(myConcat,len(myConcat)-1) from (
select c.id, replace(replace(CAST(CAST('<i'+stuff((select * from(
SELECT A.[id] ,
Split.a.value('.', 'VARCHAR(1000)') AS String
FROM (SELECT [id],
CAST ('<M>' + REPLACE([string], ',', '</M><M>') + '</M>' AS XML) AS String
FROM TableA) AS A CROSS APPLY String.nodes ('/M') AS Split(a)) a
inner join table2 b on a.String = b.id
where a.id = c.id
FOR XML PATH ('')
),1,2,'') AS XML).query('/text') AS VARCHAR(1000)),'<text>',''),'</text>',',') myConcat
from TableA c
group by c.id
) d
Use this:
DECLARE @t TABLE(id int,value varchar(255))
INSERT INTO @t (id,value)
VALUES(1,'a1'),(2,'a2'),(3,'a3')....
SELECT *,STUFF((SELECT DISTINCT ','+value FROM @t WHERE id=t.id)
FOR XML PATH('')),1,2,' ')
FROM (SELECT DISTINCT ID FROM @t) t
DISTINCT
in the case of same id, otherwise let it go
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.