mysql update query with sub query

64

Can anyone see what is wrong with the below query?

When I run it I get:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a where a.CompetitionID = Competition.CompetitionID' at line 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

This question is tagged with mysql sql

~ Asked on 2012-07-21 01:12:32

The Best Answer is


155

The main issue is that the inner query cannot be related to your where clause on the outer update statement, because the where filter applies first to the table being updated before the inner subquery even executes. The typical way to handle a situation like this is a 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

Demo: http://www.sqlfiddle.com/#!2/a74f3/1

~ Answered on 2012-07-21 01:24:43


22

Thanks, I didn't have the idea of an UPDATE with INNER JOIN.

In the original query, the mistake was to name the subquery, which must return a value and can't therefore be aliased.

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

should do the trick for every record of Competition.

To be noticed :

The effect is NOT EXACTLY the same as the query proposed by mellamokb, which won't update Competition records with no corresponding PickPoints.

Since SELECT id, COUNT(*) GROUP BY id will only count for existing values of ids,

whereas a SELECT COUNT(*) will always return a value, being 0 if no records are selected.

This may, or may not, be a problem for you.

0-aware version of mellamokb query would be :

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)

In other words, if no corresponding PickPoints are found, set Competition.NumberOfTeams to zero.

~ Answered on 2013-09-04 12:37:50


Most Viewed Questions: