如何用MySQL CONCAT与JOIN的多行合并结果更新字段?
合并关联行的拼接结果更新目标字段
问题场景
执行以下SELECT语句时,通过CONCAT_WS和LEFT JOIN能得到对应多行结果:
select CONCAT_WS(' - ', r.spare, r.assembly, r.model) reemplazos from TblPartes p left join TblReemplazos r on p.codigo1 = r.Option where p.codigo1 = 'V4-VS07-040'
但使用常规UPDATE语句时,只会将第一行的拼接结果更新到TblPartes的stock_reemp字段:
update TblPartes As p left JOIN TblReemplazos As r On p.codigo1 = r.Option Set p.stock_reemp = CONCAT_WS(' - ', r.spare, r.assembly, r.model)
需要将所有关联行的拼接结果合并后,统一更新到对应stock_reemp字段,达到预期的合并结果。
表结构与预期结果
TblReemplazos表
| id | option | spare | assembly | model |
|---|---|---|---|---|
| 1 | V4-VS07-040 | 005050748 | 005050148 | 005050749 |
| 2 | V4-VS07-040 | 005050149 | 005050552 | 005050953 |
| 3 | V4-VS07-040 | 005052065 | 005052064 | |
| 4 | V8-VS08-080 | 8811uu33 | 8811uu44 | 8811uu55 |
TblPartes原表
| id | codigo1 | stock_reemp |
|---|---|---|
| 1 | V4-VS07-040 | |
| 2 | V8-VS08-080 |
预期TblPartes结果
| id | codigo1 | stock_reemp |
|---|---|---|
| 1 | V4-VS07-040 | 005050748 - 005050148 - 005050749 - 005050149 - 005050552 - 005050953 - 005052065 - 005052064 |
| 2 | V8-VS08-080 | 8811uu33 - 8811uu44 - 8811uu55 |
解决方案(MySQL)
核心是先通过子查询按关联字段分组,合并同组内的所有拼接结果,再关联更新目标表:
UPDATE TblPartes p JOIN ( SELECT r.option, GROUP_CONCAT(CONCAT_WS(' - ', r.spare, r.assembly, r.model) SEPARATOR ' - ') AS combined_reemplazos FROM TblReemplazos r GROUP BY r.option ) AS r_agg ON p.codigo1 = r_agg.option SET p.stock_reemp = r_agg.combined_reemplazos;
逻辑说明
- 子查询处理:对
TblReemplazos按option分组,先用CONCAT_WS拼接每行的spare、assembly、model,再用GROUP_CONCAT把同组内的所有拼接结果用' - '分隔合并成单个字符串。 - 关联更新:将
TblPartes与子查询的分组结果通过codigo1和option关联,直接把合并后的字符串赋值给stock_reemp字段。
如果需要避免空model导致的多余分隔符,可以用NULLIF过滤空值:
UPDATE TblPartes p JOIN ( SELECT r.option, GROUP_CONCAT( CONCAT_WS(' - ', r.spare, r.assembly, NULLIF(r.model, '')) SEPARATOR ' - ' ) AS combined_reemplazos FROM TblReemplazos r GROUP BY r.option ) AS r_agg ON p.codigo1 = r_agg.option SET p.stock_reemp = r_agg.combined_reemplazos;
其他数据库适配提示
如果使用PostgreSQL,替换GROUP_CONCAT为STRING_AGG即可:
UPDATE TblPartes p SET stock_reemp = r_agg.combined_reemplazos FROM ( SELECT r.option, STRING_AGG(CONCAT_WS(' - ', r.spare, r.assembly, r.model), ' - ') AS combined_reemplazos FROM TblReemplazos r GROUP BY r.option ) AS r_agg WHERE p.codigo1 = r_agg.option;
内容的提问来源于stack exchange,提问作者DIEGO L
相关产品推荐
相关产品推荐

