使用另一张表中的值更新MySQL列

322

我有两个表,它们都长得像:

id  name  value
===================
1   Joe     22
2   Derk    30

我需要根据每个表中的检查名称,将tableA中的value值复制到tableB中。

对于这个UPDATE语句有什么建议吗?

9个回答

596

除了这个答案外,如果你需要根据tableA.value动态地改变tableB.value,你可以执行以下操作:

UPDATE tableB
INNER JOIN tableA ON tableB.name = tableA.name
SET tableB.value = IF(tableA.value > 0, tableA.value, tableB.value)
WHERE tableA.name = 'Joe'

没错,在这种情况下使用 INNER JOIN 是完美的选择。我还使用了 CONCAT_WS 函数来合并另一张表中的产品名称和 SKU。 - vladkras
2
有没有使用别名的方法来实现这个? - Gellie Ann
我尝试了这个,但没有成功,因为"受影响的行"计数给出5690,但总行数是59643,为什么? 这是查询:UPDATE participants_registrations INNER JOIN participants ON participants.id = participants_registrations.participantId INNER JOIN registrations ON registrations.id = participants_registrations.registrationId LEFT JOIN groups ON (groups.id = registrations.groupId) SET registrations.groupId = groups.id, registrations.groupName = groups.name, participants.memberOfGroupName = groups.name - Sequoya
这不起作用。tableB仍然保留自己的数据而没有改变。https://wtools.io/paste-code/bzWA 基于OP和这个答案的示例。 - sniffingdoggo
1
@sniffingdoggo 这是因为你的A表和B表的数据集根本不匹配。你的INNER JOIN是在name上进行连接,而你的WHERE子句却在TableA.name上查找。 由于没有记录可以连接,JOIN操作将不会发生,因此你无法更新TableB中名称为Joe的记录,因为没有任何符合该条件的记录。 - Warren Sergent

211

你需要连接这两个表:

例如,你想要将tableA中的name值复制到tableB中,在它们有相同的ID时。

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.id = t2.id
SET t1.name = t2.name 
WHERE t2.name = 'Joe'

更新 1

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.id = t2.id
SET t1.name = t2.name 

更新2

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.name = t2.name
SET t1.value = t2.value

1
我有超过1千个不同名称和值的记录,而您现在说的是仅针对第一个记录。 - LeoSam
您可以根据需要删除或修改where子句。 - John Woo
你能否提供表A和表B的至少记录,并包含表B的新值?我很乐意帮忙 :) - John Woo
谢谢@JW웃,我已经寻找这个功能一段时间了,只是想知道,使用内连接的选择语句会是什么样子(我很好奇这里发生了什么)。谢谢。 - shnozolla
@shnozolla,类似这样的代码:SELECT t1.*, t2.* FROM tableB t1 INNER JOIN tableA t2 ON t1.name = t2.name - John Woo
显示剩余5条评论

121

第二种可能性是:

UPDATE TableB 
SET TableB.value = (
    SELECT TableA.value 
    FROM TableA
    WHERE TableA.name = TableB.name
);

9
没必要使用复杂的连接操作,只需从另一张表中更新字段的值即可。 - davidkonrad
17
是的,这种方法可以正常工作,但对于大型数据集来说非常缓慢。如果你处理的是小表格,那么这个方法还可以,但我建议对于其他情况使用如上所示的JOIN方法。 - frijj2k
1
此外,在这种情况下,由于SQL约束,表A和B不能是同一张表。 - Muhwu
如果在两个表上都为.name建立索引,那么这是否仍然会很慢呢,@frijj2k? - Steverino
@frijj2k - 当我使用JOIN方法进行操作时,然后重置表并用上述方法重复操作,发现JOIN方法速度较慢。 - Michael Sims
这个答案是错误的。有两个问题:1)这个 SQL 将会更新 TableB 中的所有行。2)如果在 TableA 中没有找到匹配的名称,子查询将返回 NULL,因此 TableB.value 将被设置为 NULL。 - Zhaoping Lu

31
    UPDATE    cities c,
          city_langs cl
    SET       c.fakename = cl.name
   WHERE     c.id = cl.city_id

3
这很简单。 - Komal
1
喜欢这个,非常多才多艺。 - ArabianMaiden

4
第二种选择也是可行的,如果你正在使用安全更新模式(并且你收到了一个错误提示,表明你尝试更新一个没有使用关键列作为WHERE条件的表),可以通过添加以下内容解决该问题:
UPDATE TableB  
SET TableB.value = (  
SELECT TableA.value  
    FROM TableA  
    WHERE TableA.name = TableB.name  
)  
**where TableB.id < X**  
;

3

将数据存储在临时表中

Select * into tempTable from table1

现在更新列

 UPDATE table1
    SET table1.FileName = (select FileName from tempTable where tempTable.id = table1.ID);

2
在我的情况下,被接受的解决方案速度太慢了。对于一个有180K行的表,更新速率大约是每秒10行。这是在连接元素上建立索引的情况下。
最终,我使用了一个过程来解决我的问题:
CREATE DEFINER=`my_procedure`@`%` PROCEDURE `rescue`()
BEGIN
    declare str VARCHAR(255) default '';
    DECLARE n INT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE cur_name VARCHAR(45) DEFAULT '';
    DECLARE cur_value VARCHAR(10000) DEFAULT '';
    SELECT COUNT(*) FROM tableA INTO n;
    SET i=0;
    WHILE i<n DO 
      SELECT namea,valuea FROM tableA limit i,1 INTO cur_name,cur_value;
      UPDATE tableB SET nameb=cur_name where valueb=cur_value;
      SET i = i + 1;
    END WHILE;

END

我希望这篇文章能够像它帮助了我一样帮助将来的某个人


-2

更新tableA表 将value字段设为tableB表的value字段 从tableB表中获取数据 条件是tableA表的name字段等于tableB表的name字段


此查询不会产生任何结果,表现出对 SQL 的极差理解,请不要使用它。 - Heinrich supports Monica
已经测试并且能够准确地输出结果。 - Ashish Saxena

-8

如果两个表中有共同的字段,那就非常简单!

表1 = 你想要更新的表格。 表2 = 你取数据的表格。

  1. 在表1中查询并找到共同字段的值。
  2. 循环遍历并根据表1的值在表2中找到所有数据。
  3. 再次在表1中进行更新查询。

$qry_asseet_list = mysql_query("SELECT 'primary key field' FROM `table-1`");

$resultArray = array();
while ($row = mysql_fetch_array($qry_asseet_list)) {
$resultArray[] = $row;
}



foreach($resultArray as $rec) {

    $a = $rec['primary key field'];

    $cuttable_qry = mysql_query("SELECT * FROM `Table-2` WHERE `key field name` = $a");

    $cuttable = mysql_fetch_assoc($cuttable_qry);



    echo $x= $cuttable['Table-2 field']; echo " ! ";
    echo $y= $cuttable['Table-2 field'];echo " ! ";
    echo $z= $cuttable['Table-2 field'];echo " ! ";


    $k = mysql_query("UPDATE `Table-1` SET `summary_style` = '$x', `summary_color` = '$y', `summary_customer` = '$z' WHERE `summary_laysheet_number` = $a;");

    if ($k) {
        echo "done";
    } else {
        echo mysql_error();
    }


}

你正在使用一个不相关的例子,用PHP回答一个SQL问题。 - El Gucs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接