我的数据库中有一个表 story_category
,其中包含损坏的条目 . 下一个查询返回损坏的条目:
SELECT *
FROM story_category
WHERE category_id NOT IN (
SELECT DISTINCT category.id
FROM category INNER JOIN
story_category ON category_id=category.id);
我试图删除它们执行:
DELETE FROM story_category
WHERE category_id NOT IN (
SELECT DISTINCT category.id
FROM category
INNER JOIN story_category ON category_id=category.id);
但是我得到了下一个错误:
#1093 - 您无法在FROM子句中为更新指定目标表'story_category'
我怎么能克服这个?
14 回答
最简单的方法是在子查询中引用父查询表时使用表别名 .
示例:
将其更改为:
尝试将Select语句的结果保存在单独的变量中,然后将其用于删除查询 .
您的子查询中的
inner join
是不必要的 . 看起来您要删除story_category
中category
不在category
表中的条目 .做这个:
而不是:
根据@CheekySoft链接的the Mysql UPDATE Syntax,它在底部说 .
我猜你正在从store_category中删除,同时仍在联盟中从中进行选择 .
这是我将优先级列值更新为1的情况,如果它在表中是> = 1,并且在WHERE子句中使用同一个表上的子查询来确保至少有一行包含Priority = 1(因为那是执行更新时要检查的条件):
我知道它有点难看,但确实很好 .
您可以将所需的行ID插入临时表,然后删除该表中找到的所有行 .
这可能是@Cheekysoft分两步做的意思 .
NexusRex提供了一个very good solution,用于从同一个表中删除连接 .
如果你这样做:
你会得到一个错误 .
但是如果你将条件换成另一个选择:
它会做正确的事!!
Explanation: 查询优化器为第一个查询执行derived merge optimization(导致错误失败),但第二个查询不符合派生合并优化的条件 . 因此,优化器必须首先执行子查询 .
更新:此答案涵盖一般错误分类 . 有关如何最好地处理OP的确切查询的更具体的答案,请参阅此问题的其他答案
在MySQL中,您无法修改在SELECT部分中使用的同一个表 .
此行为记录在:http://dev.mysql.com/doc/refman/5.6/en/update.html
Maybe you can just join the table to itself
如果逻辑足够简单以重新调整查询形状,则使用适当的选择标准丢失子查询并将表连接到自身 . 这将导致MySQL将表视为两个不同的东西,允许破坏性的更改继续进行 .
Alternatively, try nesting the subquery deeper into a from clause ...
如果你绝对需要子查询,那就有一个解决方法,但由于几个原因,包括性能,它很难看:
FROM子句中的嵌套子查询创建一个隐式临时表,因此它不会更新 .
... but watch out for the query optimiser
但是,请注意,从MySQL 5.7.6开始,优化器可以优化子查询,但仍然会给出错误 . 幸运的是,
optimizer_switch
变量可用于关闭此行为;虽然我不建议将其作为短期修复或小型一次性任务 .感谢Peter V. Mørch在评论中提供此建议 .
示例技术来自Baron Schwartz,originally published at Nabble,在此进行了解释和扩展 .
如果你做不到
因为它是同一个表,你可以欺骗和做:
[更新或删除或其他]
如果有什么东西不起作用,当从前门进来时,请带上后门:
它很快 . 数据越大越好 .
试试这个
最近我不得不在同一个表中更新记录,如下所示:
这个查询怎么样希望它有所帮助