Pergunta

Eu tenho uma pergunta genérica que vou tentar explicar usando um exemplo.

Say Eu tenho uma tabela com os campos: "id", "nome", "categoria", "aparências" e "ratio"

A idéia é que eu tenho vários itens, cada uma relacionada a uma única categoria e "aparecer" várias vezes. O campo de relação deve incluir a percentagem de aparições de cada item em relação ao número total de aparições de itens na categoria.

Em pseudo-código que eu preciso é o seguinte:

  • Para cada categoria
    encontrar a soma total das aparências para itens relacionados a ela. Por exemplo, pode ser feito com (select sum("appearances") from table group by category)

  • Para cada item
    definir o valor da relação de aparências do item dividido pela soma encontrada para a categoria acima

Agora eu estou tentando conseguir isso com uma consulta atualização única, mas não consigo fazê-lo. O que eu pensei que eu deveria fazer é:

update Table T    
set T.ratio = T.appearances /   
(    
select sum(S.appearances)    
from Table S    
where S.id = T.id    
)

Mas MySQL não aceita o alias T na coluna de atualização, e eu não encontrou outras maneiras de conseguir isso.

Todas as idéias?

Foi útil?

Solução

Após as duas respostas que recebi (nenhum dos quais estava completo assim que eu escrevi o meu próprio), o que acabou fazendo é o seguinte:

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 

Ele funciona muito rapidamente. Eu também tentei com subconsulta correlacionada mas foi muito mais lento (ordens de magnitude), então eu estou furando com a junção.

Outras dicas

Use junta-se logo após UPDATE: Reference Manual - 13.2.11 ATUALIZAÇÃO Sintaxe

para ATUALIZAÇÃO table1 junção interna table2 on .... conjunto table1.foo = valor onde table2.bla = someothervalue

Com este tipo de coisas, sempre olhar para o manual. O MySQL tem um manual de referência adequada, por isso não deve ser tão difícil para obter a sintaxe direita;)

Esta é a forma como é feito em mssql, acho mysql é o mesmo ou similar:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top