You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL中如何用另一张表数据更新多列?现有语句未达预期求修正

问题分析与解决方案

你的问题出在JOIN后表B返回了两行数据,导致UPDATE操作会执行两次,后一次的更新覆盖了前一次的结果

举个具体的执行过程:原语句第一次匹配表B中Colz=10的行,会把Col1设为1234,Col2因为CASE条件不满足被设为Null,Col3设为4;第二次匹配Colz=12的行,Col1因为CASE条件不满足被设为Null,Col2设为2345,Col3再次设为4。最终结果里Col1会是Null,和你的预期不符。

正确的更新写法

我们需要先对表B按Id分组,把对应Colz值的Colx聚合出来,再和表A关联更新。这样就能确保每个Id只有一行数据参与更新,彻底避免覆盖问题。

以SQL Server为例,写法如下:

UPDATE a
SET Col1 = b.Col1_val,
    Col2 = b.Col2_val,
    Col3 = b.Coly_val
FROM A a
JOIN (
    SELECT 
        Id,
        -- 提取Colz=10对应的Colx,无匹配则保留Null
        MAX(CASE WHEN Colz = 10 THEN Colx END) AS Col1_val,
        -- 提取Colz=12对应的Colx,无匹配则保留Null
        MAX(CASE WHEN Colz = 12 THEN Colx END) AS Col2_val,
        -- Coly值一致,用MAX/MIN均可保证取到正确值
        MAX(Coly) AS Coly_val
    FROM B
    GROUP BY Id
) b ON a.Id = b.Id;

思路说明

  1. 子查询通过GROUP BY Id把表B中同一Id的多行数据合并成一行
  2. CASE配合MAX聚合函数,把不同Colz对应的Colx分别提取成独立的列
  3. 最后用聚合后的结果集更新表A,每个Id只会执行一次更新,不会出现覆盖情况

执行这个语句后,表A就能得到你想要的预期结果:

IdCol1Col2Col3
100123423454

如果是MySQL等其他数据库,语法会略有差异,但核心思路完全一致:先聚合表B的数据,再关联更新表A。

内容的提问来源于stack exchange,提问作者Harsh

火山引擎 最新活动