我有一个名为“父母”的主表和一个名为“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 c.master_id‘
-- 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
的解决方案“,如果您使用您的SQL语法错误’是使用一个子查询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;
但由于这从childtable拉每一行的开销可能比使用更多的子查询像原来的SQL更大,所以你应该在WHERE子句添加到连接的。表只能得到你需要的行
另一个有趣的方法就是这种语法,它与JOIN和WHERE子句的作用相同,但只有在您想更新具有相同值的所有行并且子查询仅返回一行时才应使用,因为子查询的结果会附加到结果并可以像任何列一样使用。
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;
你尝试过更新之前做你的计数,并将其存储伊娜变量传递到您的更新? – 2010-06-17 11:22:39
你有哪个错误?您的更新是正确的。 – ksogor 2010-06-17 11:31:25
它看起来像你有几个应该在下面工作的答案,但只是想指出,这似乎是重复的列和重复的数据之间非常规范化的设计。 – 2010-06-17 13:55:50