mysql update query with sub query

前端 未结 3 1371
臣服心动
臣服心动 2020-11-30 23:46

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 co

相关标签:
3条回答
  • 2020-12-01 00:19

    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

    0 讨论(0)
  • 2020-12-01 00:21

    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.

    0 讨论(0)
  • 2020-12-01 00:39

    For the impatient:

    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 = t.id
    SET t.count = aggregate.count
    

    That's @mellamokb's answer, as above, reduced to the max.

    0 讨论(0)
提交回复
热议问题