首页 > 解决方案 > 将 `limit` 与更新 sql 查询一起使用

问题描述

我有以下查询,我想限制它为subs表更新的行数。但它总是遇到错误,我哪里出错了?

UPDATE subs t1
        INNER JOIN imp_subscriptionlog t2 
             ON t1.subscription_id = t2.subscription_id
SET t1.cancellation_date = t2.date

WHERE t2.event = 'subscription_cancelled'
LIMIT 35

这是错误:

UPDATE 和 LIMIT 的错误使用

错误代码 1221。

标签: mysqlsqlsql-updatesql-order-byinner-join

解决方案


LIMIT仅在单表更新中允许,如文档中所述

对于单表语法,[...] 如果指定了ORDER BY子句,则按指定的顺序更新行。该LIMIT子句对可以更新的行数进行了限制。

对于多表语法,ORDER BY不能LIMIT使用。

您可以重写查询以使用相关子查询而不是连接:

update subs
set cancellation_date = (
    select t2.date
    from imp_subscriptionlog t2 
    where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
order by ???
limit 35

笔记:

  • 您应该order by在查询中指定一个子句,否则未定义哪些行将实际更新

  • 查询隐含地假设;中imp_subscriptionlog的每一行总是只有一个匹配的行 subs如果不是这种情况,那么您也必须order bylimit 1子查询中使用聚合,或者使用聚合

  • where我们还可以通过在查询中添加子句来确保在更新之前存在匹配

这是查询的“更安全”版本,它更新到另一个表中可用的最大日期值,而不修改不匹配的行:

update subs
set cancellation_date = (
    select max(t2.date)
    from imp_subscriptionlog t2 
    where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
where exists (
    select 1
    from imp_subscriptionlog t2 
    where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
order by ???
limit 35

推荐阅读