在MySQL中使用CTE更新或删除

新版本的MySQL 8.0现在支持Common Table Expressions.

根据手册:

A WITH clause is permitted at the beginning of SELECT, UPDATE, and DELETE statements:

WITH ... SELECT ...
WITH ... UPDATE ...
WITH ... DELETE ...

所以,我想,如下表所示:

ID lastName firstName
----------------------
1  Smith    Pat
2  Smith    Pat
3  Smith    Bob

我可以使用以下查询:

;WITH ToDelete AS 
(
   SELECT ID,
          ROW_NUMBER() OVER (PARTITION BY lastName, firstName ORDER BY ID) AS rn
   FROM mytable
)   
DELETE FROM ToDelete

为了删除表中的重复项,就像我在SQL Server中所做的那样.

事实证明我错了.当我尝试从MySQL Workbench执行DELETE语句时,我收到错误:

Error Code: 1146. Table ‘todelete’ doesn’t exist

当我尝试使用CTE进行更新时,我也收到错误消息.

所以,我的问题是,如何在MySQL中的UPDATE或DELETE语句的上下文中使用WITH子句(如8.0版手册中所述)?

最佳答案
这似乎是MySQL 8.x中发布的错误.从这bug report

In the 2015 version of the SQL standard, a CTE cannot be defined in UPDATE; MySQL allows it but makes the CTE read-only (we’re updating the documentation now to mention this).
This said, one could use a view instead of the CTE; then the view may be updatable, but due to the presence of window functions it is materialized into a temporary table (it is not merged) so is not updatable (we’re going to mention it in the doc as well).

All the above applies to DELETE too.

如果您按照上面的错误链接,您将看到建议使用CTE的解决方法,但它涉及以一对一的映射方式将CTE连接到原始目标表.根据您的示例,这是一个全面删除,不清楚您需要什么解决方法,继续使用CTE进行删除.

转载注明原文:在MySQL中使用CTE更新或删除 - 代码日志