如何用另一表列的拼接字符串更新SQL表列数据
用另一张表的拼接字符串更新当前表列的正确SQL语法
我尝试用另一张表某列的拼接字符串填充当前表的列,网上诸多方案(比如《如何在SQL Server中将多行文本拼接为单个字符串》这类内容)都不适用,以下是具体场景和正确解决方法:
表定义
@tbl1(待更新表)
DECLARE @tbl1 TABLE ([Id] INT, [Value] VARCHAR(10)) INSERT INTO @tbl1 ([Id]) VALUES (1),(2),(3)
初始数据:
| Id | Value |
|---|---|
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
@tbl2(数据源表)
DECLARE @tbl2 TABLE ([Id] INT, [Value] VARCHAR(10)) INSERT INTO @tbl2 ([Id],[Value]) VALUES (1,'A'),(3,'B'),(1,'C'),(2,'D'),(2,'E'),(3,'F'),(1,'G')
数据:
| Id | Value |
|---|---|
| 1 | A |
| 3 | B |
| 1 | C |
| 2 | D |
| 2 | E |
| 3 | F |
| 1 | G |
预期更新结果
更新后@tbl1的数据:
| Id | Value |
|---|---|
| 1 | ACG |
| 2 | DE |
| 3 | BF |
尝试过的无效方法
方法1:直接JOIN更新
UPDATE [t1] SET [t1].[Value] = COALESCE([t1].[Value],'') + [t2].[Value] FROM @tbl1 AS [t1] LEFT JOIN @tbl2 AS [t2] ON [t1].[Id] = [t2].[Id]
结果:仅保留每个Id对应的第一条Value,未完成拼接:
| Id | Value |
|---|---|
| 1 | A |
| 2 | D |
| 3 | B |
方法2:使用OUTER APPLY
UPDATE [t1] SET [t1].[Value] = [t2].[Val] FROM @tbl1 AS [t1] OUTER APPLY ( SELECT COALESCE([tb2].[Value],[t1].[Value]) AS [Val] FROM @tbl2 AS [tb2] WHERE [tb2].[Id] = [t1].[Id] ) AS [t2]
结果:与方法1完全相同,仅保留第一条匹配值。
方法3:错误的UPDATE+SELECT语法
UPDATE [t1] SELECT [t1].[Value] = COALESCE([t1].[Value],'') + [t2].[Value] FROM @tbl1 AS [t1] LEFT JOIN @tbl2 AS [t2] ON [t1].[Id] = [t2].[Id]
报错:Invalid object name 't1' 和 Incorrect syntax near 'SELECT'. Expecting SET.
正确解决方案
方案1:使用XML PATH(兼容SQL Server 2005及以上)
先通过XML PATH拼接每个Id对应的字符串,再关联更新@tbl1:
UPDATE t1 SET t1.[Value] = t2.ConcatValue FROM @tbl1 t1 JOIN ( SELECT Id, STUFF(( SELECT '' + [Value] FROM @tbl2 t WHERE t.Id = t2.Id ORDER BY (SELECT NULL) -- 若需固定顺序,可替换为具体字段,比如Value FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(10)'), 1, 0, '') AS ConcatValue FROM @tbl2 t2 GROUP BY Id ) t2 ON t1.Id = t2.Id
注:
ORDER BY (SELECT NULL)为无指定排序的写法,若需要按插入顺序、字典序等拼接,可替换为实际排序字段,比如ORDER BY t.Value。
方案2:使用STRING_AGG(SQL Server 2017及以上版本)
若你的SQL Server版本支持STRING_AGG函数,写法会更简洁:
UPDATE t1 SET t1.[Value] = t2.ConcatValue FROM @tbl1 t1 JOIN ( SELECT Id, STRING_AGG([Value], '') WITHIN GROUP (ORDER BY (SELECT NULL)) AS ConcatValue FROM @tbl2 GROUP BY Id ) t2 ON t1.Id = t2.Id
同样,WITHIN GROUP (ORDER BY ...)可按需指定拼接顺序。
内容的提问来源于stack exchange,提问作者swoxo
相关产品推荐
相关产品推荐

