2

查看以下 SQLFiddle 以供参考:http ://sqlfiddle.com/#!2/f02ca/1

我有两张几乎一模一样的桌子。我想确定表数据之间的差异,用另一个表中的不同数据更新一个表。

table1
|| *id* || *some_id* || *timestamp* ||
||    1 ||         A ||       01:00 ||
||    2 ||         B ||       02:00 ||
||    3 ||         B ||       01:00 ||
||    4 ||         A ||       02:00 ||
||    5 ||         A ||       03:00 ||

table2
|| *id* || *some_id* ||
||    1 ||         B ||  <-- some_id is different than table1
||    2 ||         B ||
||    3 ||         B ||
||    4 ||         A ||
||    5 ||         B ||  <-- some_id is different than table1

所以我想用some_idtable2 中的 new 更新 table1。我可以很容易地找到两个表之间的差异:

SELECT t2.id
FROM table2 t2
LEFT JOIN table1 t1 ON t1.id = t2.id
WHERE t2.some_id != t1.some_id

结果:

1, 5 (the id's of the table2 rows that have a different some_id).

我想我可以做这种类型的查询:

UPDATE table1
SET some_id = 
    (SELECT some_id FROM table2 WHERE id IN 
        (SELECT t2.id 
        FROM table2 t2
        LEFT JOIN table1 t1 ON t1.id = t2.id 
        WHERE t2.some_id != t1.some_id ))

我认为该查询将table1使用 new更新some_idtable2但仅适用some_ids于它们之间不同的行。但我收到以下错误:

SQL Error (1093): You can't specify target table 'table1' for update in FROM clause

我在正确的轨道上吗?如果是这样,我该如何解决这个问题?有没有更好或更有效的方法来实现这一点?

几点注意事项:

  1. 重要的是,我不只是更新或将所有内容插入table2table1中,因为该timestamp列。当行更新时,该列将自行更新。我想要更新的唯一table1some_idtable2. 所以本质上,该timestamp列用于显示该行上次更改的时间。
  2. 重要的是要在尽可能少的查询中完成此操作,并且要高效地完成。在我的简单示例中,每个表只有 5 行,但实际上我的表有数千行。
4

2 回答 2

1

您可能需要一个带有 JOIN 的 UPDATE:

UPDATE     table1 AS t1
INNER JOIN table2 AS t2
ON         t1.id = t2.id
SET        t1.some_id = t2.some_id
WHERE      t1.some_id != t2.some_id
;

联接与您的 SELECT 语句中的基本相同,只是它不需要是外部联接,因为据我了解,您只想更新ids 匹配的行。

这是此查询的 SQL Fiddle 演示:http ://sqlfiddle.com/#!2/58eb8/1 。

于 2013-03-10T21:26:44.837 回答
0

恐怕没有。在 MySQL 中,不能修改执行 SELECT 的同一个表。

检查这些:http ://dev.mysql.com/doc/refman/5.6/en/update.html

目前,您无法在子查询中更新表并从同一个表中进行选择。

于 2013-03-10T20:51:07.897 回答