2012-07-21 22 views
42

¿Alguien puede ver cuál es el problema con la siguiente consulta?consulta de actualización de mysql con sub consulta

Cuando lo ejecuto me sale:

# 1064 - Usted tiene un error en su sintaxis SQL; compruebe el manual que corresponde a su versión del servidor MySQL para el sintaxis derecho al uso cerca de 'a en la que a.CompetitionID = Competition.CompetitionID' en la línea 8

Update Competition 
Set Competition.NumberOfTeams = 
(
SELECT count(*) as NumberOfTeams 
FROM PicksPoints 
where UserCompetitionID is not NULL 
group by CompetitionID 
) a 
where a.CompetitionID = Competition.CompetitionID 

Respuesta

113

El principal problema es que la consulta interna no puede relacionarse con su cláusula where en la declaración externa update, porque el filtro donde se aplica primero a la tabla que se está actualizando antes de que se ejecute incluso la subconsulta interna. La forma típica de manejar una situación como esta es un multi-table update.

Update 
    Competition as C 
    inner join (
    select CompetitionId, count(*) as NumberOfTeams 
    from PicksPoints as p 
    where UserCompetitionID is not NULL 
    group by CompetitionID 
) as A on C.CompetitionID = A.CompetitionID 
set C.NumberOfTeams = A.NumberOfTeams 

Demostración: http://www.sqlfiddle.com/#!2/a74f3/1

+1

Muchas gracias, eso funcionó :) ¡Agradezca también la explicación, aplausos! – user1542043

+0

La explicación hizo de esto una muy buena respuesta. –

15

Gracias, yo no tenía la idea de una actualización con INNER JOIN.

En la consulta original, el error fue nombrar la subconsulta, que debe devolver un valor y, por lo tanto, no se puede alias.

UPDATE Competition 
SET Competition.NumberOfTeams = 
(SELECT count(*) -- no column alias 
    FROM PicksPoints 
    WHERE UserCompetitionID is not NULL 
    -- put the join condition INSIDE the subquery : 
    AND CompetitionID = Competition.CompetitionID 
    group by CompetitionID 
) -- no table alias 

debe hacer el truco para cada registro de la competencia.

para hacerse notar:

El efecto no es exactamente la misma que la consulta propuesta por mellamokb, que no va a actualizar los registros de la competición sin PickPoints correspondientes.

Desde SELECT id, COUNT(*) GROUP BY id sólo contará para los valores actuales de las identificaciones,

mientras que un SELECT COUNT(*) siempre devuelve un valor, siendo 0 si no se seleccionan los registros.

Esto puede, o no, ser un problema para usted. Versión

0-consciente de consulta mellamokb sería:

Update Competition as C 
LEFT join (
    select CompetitionId, count(*) as NumberOfTeams 
    from PicksPoints as p 
    where UserCompetitionID is not NULL 
    group by CompetitionID 
) as A on C.CompetitionID = A.CompetitionID 
set C.NumberOfTeams = IFNULL(A.NumberOfTeams, 0) 

En otras palabras, si no se encuentran PickPoints correspondientes, establecidos Competition.NumberOfTeams a cero.

4

Para los impacientes:

UPDATE target AS t 
INNER JOIN (
    SELECT s.id, COUNT(*) AS count 
    FROM source_grouped AS s 
    -- WHERE s.custom_condition IS (true) 
    GROUP BY s.id 
) AS aggregate ON aggregate.id = target.id 
SET t.count = aggregate.count 

Eso es @mellamokb 's respuesta, como el anterior, reducida al máximo.

Cuestiones relacionadas