Mise à jour: cette réponse couvre la classification générale des erreurs. Pour une réponse plus spécifique sur la meilleure façon de traiter 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 vous utilisez dans la partie SELECT.
Ce comportement est documenté à:
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 des critères de sélection appropriés. Cela amènera MySQL à voir la table comme deux choses différentes, permettant aux changements destructifs 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 moche 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 , donc elle ne compte pas comme la même table que vous mettez à jour.
... mais attention à l'optimiseur de requêtes
Cependant, sachez qu'à partir de MySQL 5.7.6 et versions ultérieures, l'optimiseur peut optimiser la sous-requête et toujours vous donner l'erreur. Heureusement, la optimizer_switch
variable peut être utilisée pour désactiver ce comportement; bien que je ne puisse pas recommander de faire cela comme quelque chose de plus 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 du baron Schwartz, initialement publié chez Nabble , paraphrasé et développé ici.