SQL Server 2008 - 使用另一个表中的值替换列中的文本值

时间:2015-06-19 18:32:25

标签: sql sql-server sql-server-2008

我试过弯曲我的谷歌无效,所以我在这里!不幸的是,我无法改变这些表的任何内容,因为它们来自我必须报告的应用程序。

在SQL Server 2008中,我尝试使用另一个表(表2)中的值替换一个文本字符串列(表1)中的多个值。

提前致谢!!

表1

id value
-------------
1  a1, a2, a3
2  a2, a3
3  a4

表2

id value
---------
a1 Value1
a2 Value2
a3 Value3
a4 Value4

期望输出

id   value
-----------------------------
1    Value1, Value2, Value3
2    Value2, Value3
3    Value4

4 个答案:

答案 0 :(得分:0)

此网站具有分隔文本拆分功能http://www.sqlservercentral.com/articles/Tally+Table/72993/

使用该函数将值拆分为临时表。使用新值替换临时表中的值。然后使用STUFF..FOR XML将记录重新组合在一起并更新您的表格。

将一个函数添加到数据库后,一个带有几个cte的查询应该能够处理所有这些。

使用Sql Fiddle

的示例

答案 1 :(得分:0)

根据@ user1221684的建议,使用http://www.sqlservercentral.com/articles/Tally+Table/72993/处的DelimitedSplit8K,你可能会想到这样的东西。使用像这样的分隔数据是一件痛苦的事。首先,您必须解析字符串,以便将其连接到另一个表,然后通过将其填充回非规范化形式来破坏。

确保如果您使用它,您就能理解该功能以及此代码正在执行的操作。这不是入门级的t-sql,它将在凌晨3点支持这个,当它在生产中断时,而不是我。

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
;

答案 2 :(得分:0)

我很抱歉提前解决这个问题:)尽管如此,它可以满足您的需求:

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

答案 3 :(得分:0)

使用此:

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
在同一个id的情况下

DISTINCT,否则就让它去吧