我的数据库中有一个表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”

我如何克服这一问题?


当前回答

子查询中的内部联接是不必要的。看起来您想要删除story_category中的条目,其中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);

执行以下操作:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category);

其他回答

NexusRex提供了一个非常好的解决方案,可以从同一个表中删除带有联接的内容。

如果您这样做:

DELETE FROM story_category
WHERE category_id NOT IN (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
)

你会得到一个错误。

但如果您将条件包装为一个以上的选择:

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
    ) AS c
)

它会做正确的事情!!

解释:查询优化器对第一个查询进行派生合并优化(这会导致它失败并出现错误),但第二个查询不符合派生合并优化的条件。因此,优化器被迫首先执行子查询。

尝试将Select语句的结果保存在单独的变量中,然后将其用于删除查询。

这个查询怎么样?希望有帮助

DELETE FROM story_category LEFT JOIN (SELECT category.id FROM category) cat ON story_category.id = cat.id WHERE cat.id IS NULL

根据@CheekySoft链接的Mysql UPDATE语法,它就在底部。

当前,无法更新表并从子查询中的同一表中进行选择。

我猜您正在从store_category中删除,同时仍在联盟中从中进行选择。

最近,我不得不更新同一个表中的记录,如下所示:

UPDATE skills AS s, (SELECT id  FROM skills WHERE type = 'Programming') AS p
SET s.type = 'Development' 
WHERE s.id = p.id;