Requête de mise à jour de mysql avec sous requête

Quelqu’un peut-il voir ce qui ne va pas avec la requête ci-dessous?

Quand je le lance, je reçois:

# 1064 – Vous avez une erreur dans votre syntaxe SQL; Consultez le manuel correspondant à votre version du serveur MySQL pour connaître la syntaxe appropriée à utiliser près de ‘a où a.CompetitionID = Competition.CompetitionID’ à la ligne 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 

Le problème principal est que la requête interne ne peut pas être liée à votre clause where sur l’instruction de update externe, car le filtre where s’applique d’abord à la table en cours de mise à jour avant même l’exécution de la sous-requête interne. La manière habituelle de gérer une situation comme celle-ci est une mise à jour à plusieurs tables .

 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 

Démo: http://www.sqlfiddle.com/#!2/a74f3/1

Merci, je n’ai pas eu l’idée d’une mise à jour avec INNER JOIN.

Dans la requête d’origine, l’erreur était de nommer la sous-requête, qui doit renvoyer une valeur et ne peut donc pas être aliasée.

 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 

devrait faire le tour pour chaque record de la concurrence.

A noter:

L’effet n’est PAS EXACTEMENT identique à la requête proposée par mellamokb, qui ne mettra pas à jour les enregistrements de la compétition sans les points PickPoints correspondants.

Puisque l’ SELECT id, COUNT(*) GROUP BY id ne comptera que pour les valeurs existantes des identifiants,

tandis qu’un SELECT COUNT(*) renverra toujours une valeur, étant 0 si aucun enregistrement n’est sélectionné.

Cela peut ou non être un problème pour vous.

La version 0-aware de la requête mellamokb serait:

 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 d’autres termes, si aucun PickPoints correspondant n’est trouvé, définissez Competition.NumberOfTeams sur zéro.

Pour les impatients:

 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 

C’est la réponse de @mellamokb , comme ci-dessus, réduite au maximum.