MySQL/SQL:Обновление с помощью коррелированного подзапроса из самой обновленной таблицы.
-
22-07-2019 - |
Вопрос
У меня общий вопрос, который я попытаюсь объяснить на примере.
Скажем, у меня есть таблица с полями:«идентификатор», «имя», «категория», «внешний вид» и «соотношение»
Идея состоит в том, что у меня есть несколько элементов, каждый из которых относится к одной категории и «появляется» несколько раз.Поле соотношения должно включать процент появлений каждого элемента от общего количества появлений элементов в категории.
В псевдокоде мне нужно следующее:
Для каждой категории
найдите общую сумму появлений связанных с ним предметов.Например, это можно сделать с помощью (select sum("appearances") from table group by category
)Для каждого предмета
установите значение соотношения как внешний вид элемента, разделенный на сумму, найденную для категории выше
Теперь я пытаюсь добиться этого с помощью одного запроса на обновление, но, похоже, не могу этого сделать.Я подумал, что мне следует сделать следующее:
update Table T
set T.ratio = T.appearances /
(
select sum(S.appearances)
from Table S
where S.id = T.id
)
Но MySQL не принимает псевдоним T в столбце обновления, и других способов добиться этого я не нашел.
Есть идеи?
Решение
После двух полученных мной ответов (ни один из которых не был полным, поэтому я написал свой), в конечном итоге я сделал следующее:
UPDATE Table AS target
INNER JOIN
(
select category, appearances_sum
from Table T inner join (
select category as cat, sum(appearances) as appearances_sum
from Table
group by cat
) as agg
where T.category = agg.cat
group by category
) as source
ON target.category = source.category
SET target.probability = target.appearances / source.appearances_sum
Это работает очень быстро.Я также пробовал использовать коррелированный подзапрос, но он был намного медленнее (на несколько порядков), поэтому я придерживаюсь соединения.
Другие советы
Используйте объединения сразу после UPDATE:Справочное руководство – 13.2.11 Синтаксис ОБНОВЛЕНИЯ
Так что обновите таблицу 1 Внутреннее соединение Table2 на ....Установите Table1.foo = значение, где Table2
С такими вещами всегда смотрите руководство.У MySql есть подходящее справочное руководство, поэтому подобрать правильный синтаксис не составит труда;)
Вот как это делается в mssql, думаю, в mysql то же самое или похожее:
create table T (id int, ratio float, appearances int)
insert T values (1, null, 2)
insert T values (1, null, 3)
update T
set ratio = cast(appearances as float)/ agg.appearancesSum
from T join (
select id, sum(appearances) as appearancesSum
from T
group by id
) as agg on t.id = agg.id