Mise à jour :cette réponse couvre la classification générale des erreurs. Pour une réponse plus précise sur la meilleure façon de gérer la requête exacte de l'OP, veuillez consulter les autres réponses à cette question
Dans MySQL, vous ne pouvez pas modifier la même table que celle que vous utilisez dans la partie SELECT.
Ce comportement est documenté sur :http://dev.mysql.com/doc/refman/5.6/en/update.html
Peut-être que vous pouvez simplement joindre la table à elle-même
Si la logique est suffisamment simple pour remodeler la requête, perdez la sous-requête et joignez la table à elle-même, en utilisant les critères de sélection appropriés. Cela amènera MySQL à voir la table comme deux choses différentes, permettant aux changements destructeurs d'aller de l'avant.
UPDATE tbl AS a
INNER JOIN tbl AS b ON ....
SET a.col = b.col
Vous pouvez également essayer d'imbriquer la sous-requête plus profondément dans une clause from...
Si vous avez absolument besoin de la sous-requête, il existe une solution de contournement, mais elle est laide pour plusieurs raisons, notamment les performances :
UPDATE tbl SET col = (
SELECT ... FROM (SELECT.... FROM) AS x);
La sous-requête imbriquée dans la clause FROM crée une table temporaire implicite , il ne compte donc pas comme la même table que vous mettez à jour.
... mais attention à l'optimiseur de requête
Cependant, méfiez-vous qu'à partir de MySQL 5.7 .6
et au-delà, l'optimiseur peut optimiser la sous-requête et toujours vous donner l'erreur. Heureusement, le optimizer_switch
variable peut être utilisée pour désactiver ce comportement ; bien que je ne puisse pas recommander de le faire comme autre chose qu'une solution à court terme ou pour de petites tâches ponctuelles.
SET optimizer_switch = 'derived_merge=off';
Merci à Peter V. Mørch pour ce conseil dans les commentaires.
L'exemple de technique provenait de Baron Schwartz, publié à l'origine sur Nabble , paraphrasé et étendu ici.