带有子查询的 MySQL UPDATE TABLE 不会先执行子查询

Posted

技术标签:

【中文标题】带有子查询的 MySQL UPDATE TABLE 不会先执行子查询【英文标题】:MySQL UPDATE TABLE with subquery does not execute subquery first 【发布时间】:2020-10-25 16:56:59 【问题描述】:

我有一个生成 3 列的查询(ApplicationIDFamilySizeGrantID)。在初始查询中,FamilySize 是一个计数。该查询有效,大约需要 5 分钟才能产生结果,并产生预期的结果。查询是这样的:

SELECT t1.ApplicationID, COUNT(*) FamilySize, t1.GrantID
FROM 
(
 SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
 FROM CONTINUITYCHILD_P `child`
 JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
 UNION 
 SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
 FROM CONTINUITYPARENT_P `par`
 JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID

初始查询运行良好。但是,我想用它来更新另一个表中的字段,其中GrantID 匹配。我正在使用 MariaDB,但查看了 mysql 8 文档,因为 MariaDB 和 MySQL 应该具有兼容的语法:https://dev.mysql.com/doc/refman/8.0/en/update.html

我正在尝试使用与此类似的语法:

UPDATE t1, t2
SET t1.column = t2.column
WHERE t1.column2 = t2.column2

这样会将我的整个初始查询转换为表 (t2),并且正在更新的表 (t1) 将能够匹配 t1 和 t2 之间的列。

这是结果查询:

UPDATE METRICS_G m,
(
SELECT ApplicationID, COUNT(*) FamilySize, GrantID
FROM 
(
 SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
 FROM CONTINUITYCHILD_P `child`
 JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
 UNION 
 SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
 FROM CONTINUITYPARENT_P `par`
 JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID

) t2
SET m.FamilySize = t2.FamilySize
WHERE m.GrantID = t2.GrantID;

查询没有出错,并在 3 毫秒内返回,影响 0 行。

这一定意味着子查询没有被执行,因为该查询通常需要几分钟才能返回。

在 UPDATE 语句中使用查询的输出作为表来匹配我做错了什么?

【问题讨论】:

选择加入 METRICS_G 的位置,然后首先选择并查看它是否找到任何行。您可以使用此结果选择来组合列。但是 forst ypoui 必须查看是否有任何连接的行 ar all BOoom...你解决了。 METRICS_G 是一个空表。我正在使用测试表,但它是空的。谢谢! 【参考方案1】:

您必须在UPDATE 语句中将查询连接到表METRICS_G

UPDATE METRICS_G m
INNER JOIN (
  SELECT ApplicationID, COUNT(*) FamilySize, GrantID
  FROM (
    SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
    FROM CONTINUITYCHILD_P `child`
    JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
    UNION 
    SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
    FROM CONTINUITYPARENT_P `par`
    JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
  ) t1
  GROUP BY ApplicationID
) t2 ON m.GrantID = t2.GrantID
SET m.FamilySize = t2.FamilySize

【讨论】:

根据 MySQL 8 文档,这不是真的。您可以简单地包含两个表,例如:UPDATE t1、t2,然后使用 WHERE 条件来匹配它们。 @jonnyjandles UPDATE t1, t2... 是一个多表更新,当您想要更新 2 个表时使用它。这是你想要的吗?我不这么认为。 真的会更新两个表吗?为什么?我只设置 t1.column = t2.column。我没有将 t2.column 设置为任何内容。 @jonnyjandles 在您的情况下,它不会更新两个表,尤其是当第二个表不是表而是不可更新的查询时。我在评论中说的是您使用的语法不适合 UPDATE 语句。正确的做法是加入。 我理解并感谢您对进行此查询的正确方法的纠正!

以上是关于带有子查询的 MySQL UPDATE TABLE 不会先执行子查询的主要内容,如果未能解决你的问题,请参考以下文章

关联子查询Update语句

oracle中的update语句能用相关子查询么?

MYSQL的UPDATE子查询,UPDATE时避免使用子查询

在 Django 的 ORM 中使用带有 UPDATE 的子查询

MYSQL UPDATE 查询多个值

MySQL的更新语句update中可以用子查询吗?