更新中的连接值

时间:2015-01-27 18:31:43

标签: sql-server tsql sql-update

好吧,我一直在靠墙撞击大约20分钟,我似乎无法想出这个。我有两个表,每个表都有一个公共字段(ID),我想要做的是将#T2和UDValue列的值连接到#T1的UDValue列

CREATE TABLE #T1(ID INT, UDValue NVARCHAR(50))
CREATE TABLE #T2(ID INT, UDValue NVARCHAR(50))

INSERT INTO #T1(ID)
    VALUES(1)

INSERT INTO #T2(ID, UDValue)
    VALUES(1, 'Tom')
          ,(1, 'Dick')
          ,(1, 'Harry')
          ,(2, 'Chevy')
          ,(3, 'Apple')
          ,(2, 'Ford')

UPDATE #T1
    SET UDValue = COALESCE(t1.UDValue, '') + t2.UDValue + ','
FROM
    #T1 AS t1
       INNER JOIN #T2 AS t2 ON t2.ID = t1.ID

SELECT * FROM #T1

DROP TABLE #T1
DROP TABLE #T2

所以我要找的是看到我的数据:

ID  UDValue
1, Tom,Dick,Harry
2, Chevy,Ford
3, Apple

但这就是我得到的:

ID  UDValue
1   Tom,
2   Chevy,
3   Apple,

我想避免不得不遍历每一行,但我没有看到任何替代方案。

3 个答案:

答案 0 :(得分:2)

您可以使用stufffor xml path来连接列值 您可以使用corelated sub query来获取逗号分隔值

在数据库中将其作为逗号分隔值存储也不是一个好主意。

;with cte
as
(
select ID,         
         stuff((select  ','+ T2.UDValue 
         from #T2 T2
         where T2.ID = T1.ID
         FOR XML PATH ('')), 1,1,'') as NewValue
from #T1 T1
)
update #T1 
set UDValue = cte.NewValue
from cte
join #T1 
on cte.ID = #T1.ID

select * from #T1

答案 1 :(得分:1)

更新中的连接值:

create table #T (Id int, Value varchar(50), primary key (Id, value));

declare @Id int;
declare @Value varchar(500);

insert into #T 
    (   Id  ,   Value   )
values
    (   1   ,   'Tom'   ),
    (   1   ,   'Dick'  ),
    (   1   ,   'Harry' ),
    (   2   ,   'Chevy' ),
    (   3   ,   'Apple' ),
    (   2   ,   'Ford'  );

update #T set    
   @Value = case when @Id is null or @Id = Id then @Value else null end,
   @Value = Value = coalesce(@Value + ', ', '') + Value,
   @Id = Id;

select Id, max(Value) from #T group by Id;

drop table #T;

仅当在表上定义“主键”时,该示例才有效。

有关“Quirky Update”的更多信息,请参阅Solving the Running Total and Ordinal Rank Problems

答案 2 :(得分:0)

这是我到目前为止所提出的,但我不确定这是最有效的方法:

CREATE TABLE #T1(ID INT, UDValue NVARCHAR(50))
CREATE TABLE #T2(ID INT, UDValue NVARCHAR(50))

INSERT INTO #T1(ID)
    VALUES(1)
          ,(2)
          ,(3)

    INSERT INTO #T2(ID, UDValue)
        VALUES(1, 'Tom')
              ,(1, 'Dick')
              ,(1, 'Harry')
              ,(2, 'Chevy')
              ,(3, 'Apple')
              ,(2, 'Ford')

DECLARE @id INT = 1, @UDValue NVARCHAR(MAX)

WHILE(@ID < 4)
    BEGIN
       SELECT @UDValue = STUFF((SELECT DISTINCT N',' + UDValue
                          FROM
                             #T2
                          WHERE ID = @ID
                        ORDER BY N',' + UDValue
                        FOR XML PATH(''), TYPE
                          ).value(N'.[1]',N'nvarchar(max)'),1,1,'');

       UPDATE #T1
          SET UDValue = @UDValue
       FROM
          #T1 AS t1
       WHERE
          t1.ID = @ID

       SELECT @ID += 1
    END

SELECT * FROM #T1

DROP TABLE #T1
DROP TABLE #T2