【问题标题】:MySQL select and update multiple rows from same tableMySQL从同一个表中选择并更新多行
【发布时间】:2015-09-19 05:51:44
【问题描述】:

通常我想从我的数据库中的orders 表中选择在某个日期之后创建的行,然后将所有选定行的office_id 字段更新为特定值12。 我的 MySQL 版本是 5.5.43。 起初,我试图将它放在一个 SQL 语句中,如下所示:

UPDATE `order`
SET office_id = 12
WHERE id IN (  
  SELECT id
  FROM  `order` 
  WHERE created_at >= DATE_FORMAT( '2014-07-02 00:00:00', '%Y.%m.%d 00:00:00' ) 
);

我得到了错误:#1093 - You can't specify target table 'order' for update in FROM clause

接下来我尝试使用SELECT .. FOR UPDATE 语句来执行此操作,如下所示:

START TRANSACTION;

SELECT id
FROM  `order` 
WHERE created_at >= DATE_FORMAT( '2014-07-02 00:00:00', '%Y.%m.%d 00:00:00' ) 
FOR UPDATE;

UPDATE `order`
SET office_id = 12
WHERE id IN ( id );

COMMIT;

哪个有效,但如果 SELECT .. FOR UPDATE 语句不返回任何行,则 office_id = 12 将应用于 orders 表中的所有行,我绝对不希望这样做。

我正在寻求帮助,以修改第一个或第二个解决方案以进行适当的工作。

【问题讨论】:

    标签: mysql sql select sql-update mysql-error-1093


    【解决方案1】:

    这比你做的要简单得多。您可以将 WHERE 子句直接应用于 UPDATE 语句。

    UPDATE `order`
        SET office_id = 12
        WHERE created_at >= DATE_FORMAT( '2014-07-02 00:00:00', '%Y.%m.%d 00:00:00' );
    

    【讨论】:

    • 大概,idorder 中是唯一的,在这种情况下应该可以。但是,这两个查询不一定是等效的。您正在对数据结构做出一些假设。
    • 非常感谢。是的,id 是独一无二的。这是在这种特殊情况下的最佳解决方案。
    【解决方案2】:

    如果id 可以在order 中重复,那么您可以使用join 来表达查询:

    UPDATE `order` o JOIN
           (SELECT distinct o.id
            FROM  `order` o
            WHERE created_at >= DATE_FORMAT( '2014-07-02 00:00:00', '%Y.%m.%d 00:00:00' 
           ) oo
           ON o.id = oo.id
        SET o.office_id = 12;
    

    【讨论】:

    • 感谢您的评论。我在稍微不同的情况下使用了您的解决方案,它与JOIN 完美配合
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多