在更新中连接值

Concatenating Value in 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,

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

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

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

您可以使用 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

更新中的连接值:

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;

只有在 table 上定义了 "primary key" 时,该示例才有效。

关于 "Quirky Update" 的更多信息在 Solving the Running Total and Ordinal Rank Problems