MySQL/SQL:Обновление с помощью коррелированного подзапроса из самой обновленной таблицы.

StackOverflow https://stackoverflow.com/questions/839938

Вопрос

У меня общий вопрос, который я попытаюсь объяснить на примере.

Скажем, у меня есть таблица с полями:«идентификатор», «имя», «категория», «внешний вид» и «соотношение»

Идея состоит в том, что у меня есть несколько элементов, каждый из которых относится к одной категории и «появляется» несколько раз.Поле соотношения должно включать процент появлений каждого элемента от общего количества появлений элементов в категории.

В псевдокоде мне нужно следующее:

  • Для каждой категории
    найдите общую сумму появлений связанных с ним предметов.Например, это можно сделать с помощью (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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top