Обновление: этот ответ охватывает общую классификацию ошибок. Чтобы получить более конкретный ответ о том, как лучше всего обрабатывать точный запрос ОП, см. Другие ответы на этот вопрос.
В MySQL вы не можете изменить ту же таблицу, которую используете в части SELECT.
Это поведение описано на странице :
http://dev.mysql.com/doc/refman/5.6/en/update.html.
Может быть, вы можете просто присоединиться к столу к себе
Если логика достаточно проста, чтобы изменить запрос, потеряйте подзапрос и присоедините таблицу к себе, используя соответствующие критерии выбора. Это приведет к тому, что MySQL увидит таблицу как две разные вещи, позволяющие вносить деструктивные изменения.
UPDATE tbl AS a
INNER JOIN tbl AS b ON ....
SET a.col = b.col
В качестве альтернативы попробуйте вложить подзапрос глубже в предложение from ...
Если вам абсолютно необходим подзапрос, есть обходной путь, но он уродлив по нескольким причинам, включая производительность:
UPDATE tbl SET col = (
SELECT ... FROM (SELECT.... FROM) AS x);
Вложенный подзапрос в предложении FROM создает неявную временную таблицу , поэтому он не считается той же самой таблицей, которую вы обновляете.
... но следите за оптимизатором запросов
Тем не менее, имейте в виду , что начиная с MySQL 5.7.6 и далее, оптимизатор может оптимизировать подзапрос и все равно выдавать ошибку. К счастью, optimizer_switch
переменная может использоваться, чтобы отключить это поведение; хотя я не мог рекомендовать делать это как что-то большее, чем краткосрочное исправление или для небольших одноразовых задач.
SET optimizer_switch = 'derived_merge=off';
Спасибо Peter V. Mørch за этот совет в комментариях.
Пример техники был от барона Шварца, первоначально опубликованный в Набле , перефразированный и расширенный здесь.