У меня есть главная таблица с именем «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», либо «У вас есть ошибка в синтаксисе sql, если вы используете« 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
Решение - использовать 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 в объединенную таблицу, чтобы получить только нужные вам строки.
Другим интересным подходом является этот синтаксис, который делает то же самое, что и 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;