我有一张table 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\u category'
我怎样才能克服这个问题?
16条答案
按热度按时间wfauudbj1#
这个问题怎么样?希望有帮助
3phpmpom2#
根据@cheekysoft链接的mysql更新语法,它在底部写着。
当前,无法更新表并从子查询中的同一表中进行选择。
我猜您正在从商店类别中删除,同时仍在联盟中从中进行选择。
lxkprmvk3#
对于op试图实现的特定查询,理想且最有效的方法是根本不使用子查询。
这是你的名字
LEFT JOIN
op两个查询的版本:注:
DELETE s
将删除操作限制为story_category
table。文档
efzxgjgh4#
这个
inner join
在您的子查询中是不必要的。您似乎要删除中的条目story_category
在哪里category_id
不在category
table。请执行以下操作:
相反:
nnvyjq4y5#
如果你做不到
因为它是同一张table,所以你可以忽悠和做:
[更新或删除或其他]
epfja78i6#
mwyxok5s7#
尝试将select语句的结果保存在单独的变量中,然后将其用于delete查询。
jfewjypa8#
至于关注点,您希望删除中的行
story_category
不存在于category
.以下是用于标识要删除的行的原始查询:
结合
NOT IN
子查询JOIN
原来的表格似乎很复杂。这可以用更直截了当的方式来表达not exists
以及相关子查询:现在很容易把它变成一个
delete
声明:这个query可以在任何mysql版本上运行,也可以在我所知道的大多数其他数据库中运行。
db小提琴演示:
pcrecxhr9#
更新:这个答案涵盖了一般错误分类。有关如何最好地处理op的确切查询的更具体的答案,请参阅此问题的其他答案
在mysql中,不能修改select部分中使用的同一个表。
此行为记录在:http://dev.mysql.com/doc/refman/5.6/en/update.html
也许你可以把table连起来
如果逻辑足够简单,可以重新调整查询的形状,则会丢失子查询并使用适当的选择条件将表连接到自身。这将导致mysql将表视为两个不同的东西,从而允许进行破坏性的更改。
或者,尝试将子查询嵌套到from子句中。。。
如果您确实需要子查询,那么有一个解决方法,但是它有几个原因,包括性能:
from子句中的嵌套子查询创建了一个隐式临时表,因此它不算作您正在更新的同一个表。
... 但要注意查询优化程序
但是,请注意,从MySQL5.7.6及更高版本开始,优化程序可能会优化子查询,但仍然会给出错误。幸运的是
optimizer_switch
变量可以用来关闭这种行为;尽管我不建议这样做仅仅是一个短期的解决方案,或者是一个小的一次性任务。多亏了彼得五世。米ørch在评论中对此建议表示感谢。
示例技术来自baron schwartz,最初发表在nabble,在这里进行了解释和扩展。
xe55xuns10#
试试这个
ncgqoxb011#
nexusrex为从同一个表中删除with join提供了一个非常好的解决方案。
如果您这样做:
你会得到一个错误。
但如果将条件 Package 在一个或多个选择中:
它会做正确的事!!
说明:查询优化器对第一个查询执行派生合并优化(这会导致查询失败并出现错误),但第二个查询不符合派生合并优化的条件。因此优化器必须首先执行子查询。
wmvff8tz12#
最简单的方法是在子查询中引用父查询表时使用表别名。
例子:
更改为:
hec6srdp13#
如果有东西不起作用,从前门进来时,从后门进来:
很快。数据越大越好。
p1iqtdky14#
最近我不得不更新同一个表中的记录,我的做法如下:
o4tp2gmn15#
您可以将所需行的id插入临时表,然后删除该表中找到的所有行。
这可能就是@cheekysoft所说的分两步完成的意思。