2009-05-08 15 views
19

Tengo una pregunta genérica que trataré de explicar con un ejemplo.MySQL/SQL: actualización con subconsulta correlacionada desde la tabla actualizada en sí

Decir que tengo una tabla con los campos: "id", "nombre", "categoría", "apariencias" y "proporción"

La idea es que tengo varios artículos, cada uno relacionado con un único categoría y "aparece" varias veces. El campo de relación debe incluir el porcentaje de las apariciones de cada elemento del número total de apariciones de los elementos en la categoría.

En pseudocódigo lo que necesito es el siguiente:

  • Para cada categoría
    encontrar la suma total de las apariencias para los artículos relacionados con el mismo. Por ejemplo, se puede hacer con (select sum("appearances") from table group by category)

  • Para cada elemento
    establecer el valor de la relación como apariciones del elemento dividido por la suma encontrados para la categoría anterior

Ahora estoy tratando de lograr esto con una sola consulta de actualización, pero parece que no puede hacerlo. Lo que pensé que debería hacer es:

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

Pero MySQL no acepta el alias T en la columna de la actualización, y que no encontrar otras maneras de lograr esto.

¿Alguna idea?

Respuesta

45

Después de las dos respuestas que recibí (ninguna de las cuales estaba completa, así que escribí la mía), lo que finalmente hice fue de la siguiente manera:

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 

Funciona muy rápido. También probé con la subconsulta correlacionada, pero fue mucho más lento (órdenes de magnitud), así que me quedo con la unión.

+0

Seleccione una respuesta como respuesta, de modo que esta pregunta se elimine de la lista de preguntas sin respuesta :) –

+1

@Frans: Tuve que esperar 48 horas antes de poder hacerlo, reglas de desbordamiento de pila :) –

+0

Niza. ¡Gracias por tomarse el tiempo de dar un ejemplo completo! – Ben

3

Ésta es la forma en que se lleva a cabo en mssql, creo que MySQL es la misma o 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 
+0

Lo sentimos, esto no funciona en MySQL. No estoy bajando la votación ya que estoy seguro de que funciona en mssql ... –

6

uso se une a la derecha después de la actualización: unirse Reference Manual – 13.2.11 UPDATE Syntax

por lo ACTUALIZACIÓN tabla1 interior TABLA2 sucesivamente. ... set table1.foo = valor donde table2.bla = someothervalue

Con este tipo de cosas, siempre mire el manual. MySql tiene un manual de referencia adecuado, por lo que no debería ser tan difícil obtener la sintaxis correcta;)

+0

Gracias, lo intentaré tan pronto como pueda. Y, por cierto, hice RTFM e intenté todo lo que tenía sentido antes de publicar la pregunta :) –

+0

gracias, la entrada manual no me ha aclarado la solución.positivo para usted también –

Cuestiones relacionadas