mysql - 有没有办法优化这个更新查询?

标签 mysql sql sql-update mysql-error-1111

我有一个名为“parent”的主表和一个名为“childs”的相关表

现在,我对主表运行查询,以使用子表中的总和更新一些值,如下所示。

UPDATE master m SET
    quantity1 = (SELECT SUM(quantity1) FROM childs c WHERE c.master_id = m.id),
    quantity2 = (SELECT SUM(quantity2) FROM childs c WHERE c.master_id = m.id),
    count =  (SELECT COUNT(*) FROM childs c WHERE c.master_id = m.id)
WHERE master_id = 666;

这按预期工作,但不是一个好的样式,因为我基本上对同一结果进行多个 SELECT 查询。有没有办法优化它? (首先进行查询并存储值不是一种选择。

我尝试过这个:

UPDATE master m SET (quantity1, quantity2, count) = (
    SELECT SUM(quantity1), SUM(quantity2), COUNT(*)
       FROM childs c WHERE c.master_id = m.id
) WHERE master_id = 666;

但这不起作用。

更新:这是解决方案,感谢大家:

你可以这样做:

UPDATE master m
  INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = c.quantity1,
    master.count = 1

如果您一次只有一个子记录。但是,如果您想在连接表中使用像 SUM() 这样的组函数,则不起作用。如果您保留“group by”部分,则会收到“无效使用组函数”信息,或者收到“如果您使用“GROUP BY c.master_id”,则 sql 语法中有错误”

-- This doesnt work :(
UPDATE master m
  INNER JOIN childs c ON m.master_id = c.master_id
SET master.quantity1 = SUM(c.quantity1),
    master.count = COUNT(c.*)
GROUP by c.master_id

解决方案是将 JOIN 与子查询一起使用:

UPDATE master m
  INNER JOIN 
  (
    SELECT   master_id,
             SUM(quantity1) as quantity1,
             COUNT(*) as count
    FROM     childs c 
    GROUP BY master_id
  ) c
  ON c.master_id = m.master_id
SET m.quantity1 = c.quantity1,
    m.count = c.count
WHERE   m.master_id = 666;

但是,由于这会从子表中提取每一行,因此开销可能会比在原始 SQL 中使用更多子查询更大。因此,您应该向连接表添加一个 WHERE 子句,以仅获取您需要的行。

另一种有趣的方法是这种语法,它的作用与使用 WHERE 子句的 JOIN 相同,但只有当您想用相同的值更新所有行并且子查询仅返回一行时,才应该使用 if ,因为结果来自子查询会附加到结果中,并且可以像任何列一样使用。

UPDATE master m,
    (
      SELECT SUM(c.quantity1) as sum_of_quantity,
      COUNT(*) as rowcount FROM child c WHERE c.master_id = 666
    ) as c
SET m.quantity1 = c.sum_of_quantity,
    m.count = c.rowcount
WHERE m.master_id = 666;

最佳答案

将 Lieven 的解决方案重写为 MySQL:

UPDATE master m 
JOIN (
    SELECT  master_id
            , SUM(quantity1) as quantity1
            , SUM(quantity2) as quantity2 
            , COUNT(*) as count
    FROM    childs c 
    GROUP BY
            master_id
) c
ON c.master_id = m.master_id
SET
  m.quantity1 = c.quantity1
  ,m.quantity2 = c.quantity2
  ,m.count = c.count
WHERE   m.master_id = 666;

关于mysql - 有没有办法优化这个更新查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3061153/

相关文章:

PHP MYSQL 如果存在则更新,如果不存在则插入?

mysql - 搜索后对数据库结果进行排序

MySQL 将求和值和虚拟列返回为 (count - sum)

php - 在单个查询中使用 OR、AND 运算符

php - 使用 C++ 将值添加到列中的现有 SQL 值

python - pymssql:在数据库连接中设置字符集选项导致连接失败

php - 不确定循环时逻辑是否正确

MySQL递归循环检测程序

c# - 更新多个字段

mysql - 从 Select 更新 - 语法和概念检查 (mySQL)