【问题标题】:#1221 - Incorrect usage of UPDATE and ORDER BY#1221 - UPDATE 和 ORDER BY 的错误使用
【发布时间】:2017-01-15 23:27:34
【问题描述】:

绕过我在其他线程中发布的问题。我试过这样的sql语句:

UPDATE user u JOIN (SELECT @i := 0) r
SET user_rank_planets = (@i := (@i + 1))
WHERE user_active=1
ORDER BY user_planets DESC

我收到错误 #1221。如果没有 order by 子句,该语句可以正常工作。 有没有人知道这个问题的解决方案?

【问题讨论】:

  • 你想做什么?
  • 当你有一个多表更新语句时,你不能使用order by子句。
  • user_planetsuser_rank_planets 是表 user 中的有效列

标签: mysql join


【解决方案1】:

在多表的情况下,不能在update语句中使用order by和limit。

引自 MySQL 文档:

对于多表语法,UPDATE 更新每个名为的表中的行 在满足条件的 table_references 中。每个匹配的行是 更新一次,即使它多次匹配条件。为了 多表语法,不能使用 ORDER BY 和 LIMIT。

UPDATE user u 
INNER JOIN 
(
    SELECT 
    *,
    (@i := (@i + 1)) AS row_number
    FROM user u 
    CROSS JOIN (SELECT @i := 0) r
    WHERE user_active=1
    ORDER BY user_planets DESC
)AS t
ON u.Primary_key = t.primary_key
SET u.user_rank_planets = t.row_number.

注意:u.Primary_keyt.primary_key替换为user表的主键。


阅读前几段http://dev.mysql.com/doc/refman/5.7/en/update.html

【讨论】:

  • 查询有效,但影响零行。
  • 也许没有什么可更新的。从一组新数据开始并确认。
  • 这在 MariaDB 中不起作用,因为 ORDER BY 在子查询中被忽略。 mariadb.com/kb/en/library/…
  • 您需要在 ORDER BY 内部订单查询之后使用 LIMIT 2147483647,因为如果没有指定限制,MySQL 和 MariaDB 将失去连接集的顺序(将以随机顺序连接)(当指定限制时 MySQL/MariaDB 创建JOIN下查询结果内存中的临时表)
【解决方案2】:

@1000111 的回答不起作用。我不知道原因,但 MySQL 只是忽略了子查询中的 ORDER BY 并使用默认顺序(通过 Primary_key)更新。 一个愚蠢的解决方案是将子查询包装在另一个子查询中以创建临时表。

UPDATE user u 
INNER JOIN 
(
    SELECT * FROM (
        SELECT *, (@i := (@i + 1)) AS row_number
        FROM user u 
        CROSS JOIN (SELECT @i := 0) r
        WHERE user_active=1
        ORDER BY user_planets DESC
    ) AS t1
) AS t
ON u.<Primary_key> = t.<Primary_key>
SET u.user_rank_planets = t.row_number

【讨论】:

  • 谢谢!看起来他们在 MySQL8 中关闭了排序
猜你喜欢
  • 2014-02-09
  • 2014-09-10
  • 2015-04-16
  • 2017-04-12
  • 2018-02-21
  • 1970-01-01
  • 2015-11-17
  • 2016-04-27
  • 1970-01-01
相关资源
最近更新 更多