views:

165

answers:

2

I have this simple query that works on all other database systems, but fails with MySQL:

UPDATE points p 
SET p.userid = 5224 
WHERE p.userid = 2532 
AND NOT EXISTS (
    SELECT 1
    FROM points q
    WHERE q.userid = 5224
    AND q.game = p.game
)

I get the following error message:

#1093 - You can't specify target table 'p' for update in FROM clause

Is there any workaround?

+3  A: 

You can't alias the main table in an UPDATE clause. This should work:

UPDATE points 
SET userid = 5224 
WHERE userid = 2532 
AND NOT EXISTS (
    SELECT 1
    FROM points q
    WHERE q.userid = 5224
    AND q.game = points.game
)
Mark Byers
and what about the AND q.game = p.game?
astander
Sorry, I missed a p. I have now changed it to points.
Mark Byers
+2  A: 

Use:

UPDATE POINTS
   SET userid = 5224 
 WHERE userid = 2532 
   AND game NOT IN (SELECT q.game
                      FROM POINTS q
                     WHERE q.userid = 5224)
OMG Ponies
FYI: `NOT IN` is faster than `NOT EXISTS` in MySQL: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/
OMG Ponies
Thanks. +1 from me, but I like Mark's answer better because NOT IN is slower on some other database systems and there the difference is huge (index vs no index), so it is more portable.
Milan Babuškov
OMG Ponies
Oracle: `NOT EXISTS`, `NOT IN` and `LEFT JOIN/IS NULL` are equivalent: http://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/
OMG Ponies
All are portable, so the point is moot
OMG Ponies
I hardly call SQL Server portable, but ok :) Oracle is not the only DBMS there is. There's Firebird, Postgred, SQLite, DB2, Informix, etc.
Milan Babuškov