SQL:使用UNION或子查询后无法使用UPDATE子句,而类似的SELECT仍然有效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL:使用UNION或子查询后无法使用UPDATE子句,而类似的SELECT仍然有效相关的知识,希望对你有一定的参考价值。

所以我目前有一个具有以下结构的数据库:

  • wp_giantbomb_game_list(post_id,重要)
  • wp_game_attribute_company(ID,重要)
  • wp_game_relation_publisher(ID,game_id,attribute_id)
  • wp_game_relation_developer(ID,game_id,attribute_id)

重要的标签是一个布尔值,表示游戏是否重要。我目前所做的是手动设置公司。我现在想要创建一个查询,将所有游戏设置为重要,要么将开发人员或发布者设置为重要。发布者和开发者关系通过“game_relation”表给出,其中game_id链接到“wp_giantbomb_game_list”和“attribute_id”。

因此,我的第一个目标是尝试将两个关系表中的数据合并为一个。毕竟,出版商或开发商是否被设置为“重要”对我来说无关紧要。

我使用以下查询返回碰巧有重要发布者或开发者的所有“game_id”标记

SELECT PUB.game_id FROM wp_game_relation_publisher PUB INNER JOIN 
wp_game_attribute_company COM ON PUB.attribute_id = COM.ID WHERE COM.important = 1 
UNION SELECT DEV.game_id FROM wp_game_relation_developer DEV INNER JOIN
wp_game_attribute_company COM ON DEV.attribute_id = COM.ID WHERE COM.important = 1 
ORDER BY game_id ASC;

这个查询非常快,并且达到了目的。现在我只想将game_id与WHERE IN子句ala一起使用

SELECT * FROM `wp_giantbomb_game_list` GAMELIST WHERE GAMELIST.post_id IN (
    SELECT PUB.game_id FROM wp_game_relation_publisher PUB INNER JOIN 
    wp_game_attribute_company COM ON PUB.attribute_id = COM.ID WHERE COM.important = 1 
    UNION SELECT DEV.game_id FROM wp_game_relation_developer DEV INNER JOIN
    wp_game_attribute_company COM ON DEV.attribute_id = COM.ID WHERE COM.important = 1 
    ORDER BY game_id ASC);

此查询无效。 phpMyAdmin根本没有回复导致我重新加载该网站。然后我尝试了一个没有UNION的解决方法,只需在OR子句中添加WHERE IN

SELECT * FROM `wp_giantbomb_game_list` GAMELIST WHERE GAMELIST.post_id IN(
    SELECT PUB.game_id FROM wp_game_relation_publisher PUB INNER JOIN
    wp_game_attribute_company COM ON PUB.attribute_id = COM.ID WHERE COM.important = 1)
    or GAMELIST.post_id IN (SELECT DEV.game_id FROM wp_game_relation_developer DEV INNER JOIN
    wp_game_attribute_company COM ON DEV.attribute_id = COM.ID WHERE COM.important = 1 );

这有效,但随后使用类似的更新语句导致PHPMyAdmin不再做出反应。

UPDATE `wp_giantbomb_game_list` GAMELIST SET important = 1 WHERE GAMELIST.post_id IN(
    SELECT PUB.game_id FROM wp_game_relation_publisher PUB INNER JOIN
    wp_game_attribute_company COM ON PUB.attribute_id = COM.ID WHERE COM.important = 1)
    or GAMELIST.post_id IN (SELECT DEV.game_id FROM wp_game_relation_developer DEV INNER JOIN
    wp_game_attribute_company COM ON DEV.attribute_id = COM.ID WHERE COM.important = 1 );

所以现在我根本不知道会发生什么。我的问题是,有谁知道发生了什么,有谁知道如何解决这个问题?

非常感谢任何提前来这里的人!

答案

尝试使用EXISTS

UPDATE `wp_giantbomb_game_list` gl
    SET important = 1
    WHERE EXISTS (SELECT 1
                  FROM wp_game_relation_publisher p INNER JOIN
                       wp_game_attribute_company c
                       ON p.attribute_id = c.ID
                  WHERE c.important = 1 AND gl.post_id = p.game_id
                 ) OR
          EXISTS (SELECT 1
                  FROM wp_game_relation_developer d INNER JOIN
                       wp_game_attribute_company c
                       ON d.attribute_id = c.ID 
                  WHERE d.important = 1 AND gl.post_id = d.game_id
                 ) ;

然后,这可以利用以下索引:

  • wp_game_relation_publisher(post_id, attribute_id)
  • wp_game_attribute_company(id, important)
  • wp_game_relation_developer(game_id, attribute_id)
另一答案

是的,我尝试使用你的代码,它有同样的问题。但是这让我挖了一点,我看到外键上没有任何索引。为外键添加了几个BTREE索引,现在我和我的答案中给出的代码完全正常。

非常感谢您的帮助,并对给您带来的不便表示歉意!

以上是关于SQL:使用UNION或子查询后无法使用UPDATE子句,而类似的SELECT仍然有效的主要内容,如果未能解决你的问题,请参考以下文章

mysql explain结果含义

SQL中Union与Union All的区别

mysql 优化 explain

内联T-SQL或子查询

sql中,只使用union和先union all再distinct,两种方式哪个效率高?

SQL视图提示无法使用Union all求大神帮忙