简体   繁体   中英

SQL Server 2008 - Replace Text Values in Column with Values from Another Table

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM