2016-09-05 38 views
0

我有一个包含游戏中生物的数据库。您无法在FROM子句中指定目标表'生物'进行更新

2表:

“creature_template”含有相对于生物

“生物”包含关于在游戏中的生物的位置的信息的所有数据。

下面是代码:

DELETE FROM 
    creature 
    WHERE 
    id not in 
    (SELECT DISTINCT 
    b.id 
    FROM 
    creature_template a inner join creature b on a.entry = b.id 
    WHERE 
    b.map != 571 
    AND a.`type` = 1 
    AND a.`type` = 10 
    ); 

的类型是生物的种类(1 =兽,10 =不指定)

我想要做的是删除所有的生物,在地图上#571并且不是野兽(类型= 1)或未指定(类型= 10)。

“map”列在“creature”表中,而“type”列在“creature_template”表中。

游戏中的每个生物都通过ID在数据库中被识别。 “生物”表有一个名为“ID”的列,其中包含这些ID,而“creature_template”表中的等价物是名为“entry”的列。

所以我必须做的是选择地图上的所有生物#571,然后排除所有的类型1和10并删除其余的。

问题是,当我执行上面的代码,我得到的错误说

我做了几个研究在这里计算器“你不能在FROM子句指定目标表‘生物’更新”和尝试了一些我找到的解决方案。

...我最终删除了“生物”表中的所有数据。幸运的是,我从昨天做的备份中获得了数据。

任何想法如何解决我的问题?

+1

如果您愿意,可以考虑遵循以下简单的两步操作步骤:1.如果您尚未这样做,请提供适当的CREATE和INSERT语句(和/或sqlfiddle),以便我们可以更轻松地复制问题。 2.如果您尚未这样做,请提供与步骤1中提供的信息相对应的所需结果集。 – Strawberry

回答

0

使用“命名的子查询黑客”:

DELETE FROM 
    creature 
    WHERE 
    id not in 
    (
    SELECT id FROM 
     (
     SELECT DISTINCT b.id 
     FROM creature_template a inner join creature b on a.entry = b.id 
     WHERE b.map != 571 AND a.`type` = 1 AND a.`type` = 10 
    ) A 
    ); 
+0

不可以。我刚刚尝试了您的解决方案,并删除了“生物”表中的所有数据。 :/ 幸运的是,我有一个备份 – NZoth

+1

@NZoth您的条件可能没有选择任何记录。并且'id不在()'中选择全部删除。首先将任何删除查询作为select进行测试。 – Mike

0

一种可能性是使用SELECTcreature提取要删除的行或您想保留的行INSERT INTO a temp table(临时表只需要包含PK列),并在DELETE语句的子查询的WHERE中使用临时表。

只是为了展示这个概念,没有测试:

SELECT DISTINCT 
    b.id 
    INTO #TempRowsToKeep 
    FROM 
    creature_template a inner join creature b on a.entry = b.id 
    WHERE 
    b.map != 571 
    AND (a.`type` = 1 or a.`type` = 10); 

DELETE FROM 
    creature 
    WHERE 
    id not in 
     (SELECT id FROM #TempRowsToKeep); 

DROP TABLE #TempRowsToKeep; 

我不是MySQL的专家,但如果从迈克的回答解决方案的工作,我认为你应该去那一个,因为它不涉及一个临时表,它只有一个语句而不是3个。事实上,当你尝试它时,它删除了你所有的行,这表明你最内层查询中的条件没有选择任何行,就像他提到的那样。实际上有一个错误肯定是造成这种情况:

AND a.`type` = 1 AND a.`type` = 10 

将始终是错误的。它应该可能是

AND (a.`type` = 1 or a.`type` = 10) 

我上面的代码包含此更正,如果您使用它,请首先仔细检查它。

+0

您是否有“在DELETE语句的子查询中使用临时表”的代码示例。部分? – NZoth

+0

@NZoth看我的编辑。无论如何,作为一个普遍的建议,不要让你恢复不愿意删除的行是“幸运的”;或者在Mike的评论推荐时首先用'SELECT'测试DELETE'条件,或者在每次尝试之前系统地进行备份。 – SantiBailors

相关问题