mysql - 在子查询中使用自引用更新行

标签 mysql sql sql-update subquery

我有一个大约有 7000 行的表,其中大约 4000 行存在由错误引起的错误。 (位置是 'null' not NULL 并且应该是其他东西。)现在我正在尝试修复几乎是所有行都可能。

UPDATE `timelog` t
SET `location`=(SELECT location
                FROM timelog tl
                WHERE tl.end_ts=t.end_ts AND location != 'null'
                ORDER BY tl.log_id DESC
                LIMIT 0,1) -- Just to make sure that I get 1 or 0 results
WHERE end_ts > '2012-01-01 00:00:00' AND location = 'null';

但我收到错误:

#1093 - You can't specify target table 't' for update in FROM clause

好吧,我在更新时似乎无法访问该行本身,我该如何解决这个问题?

也许使用临时表,但这似乎有点开销,我也必须设法复制所有不相关的行。

我还尝试使用 instat a join,如 this answer 中所述。 ,但我需要限制所选行。


根据答案,我尝试了自己的临时 View 解决方案:

CREATE OR REPLACE VIEW right_locations AS
SELECT l.*, t.end_ts, t.location, (SELECT location FROM timelog tl WHERE tl.end_ts=t.end_ts AND location != 'null' ORDER BY tl.log_id DESC LIMIT 0,1) AS "possible", t.end_location
FROM `log` l
JOIN timelog t ON t.log_id=l.log_id
WHERE l.action_id =7 AND l.ts > '2012-01-01 00:00:00'
ORDER BY end_location;

UPDATE timelog t
JOIN right_locations r ON r.log_id=t.log_id
SET t.location = r.possible
WHERE t.end_ts > '2012-01-01 00:00:00' AND t.location = 'null';

最佳答案

我发现的解决方案听起来很有趣。也许你会尝试一下?

http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/

UPDATE timelog t
SET location = (
  select location from (
    SELECT tl.location
    FROM timelog tl
    WHERE tl.end_ts = t.end_ts AND tl.location != 'null'
    ORDER BY tl.log_id DESC
    LIMIT 1
 ) as x
WHERE 
  t.end_ts > '2012-01-01 00:00:00' AND 
  t.location = 'null';

类似的东西?

关于mysql - 在子查询中使用自引用更新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9903621/

相关文章:

mysql - 当 2 个不同的行满足我的要求时返回共享列值

mysql - 使用 Windows 提取/加载 Unix .nightly 文件

sql - SQL 中的复杂求和

php - PDO 更新失败

mysql - Laravel INSERT 查询添加不相关的列,导致查询失败

php - Mysql 乘法错误

php - PDO::PARAM_INT 是多余的吗?

sql - PostgreSQL 查询不一致

sql - 使用 DATEADD 和 DATEDIFF 获取一周的开始日(星期一)时出现问题

php - 原则 - preUpdate 事件订阅者根本不会被解雇