Обновление: этот ответ охватывает общую классификацию ошибок. Более подробный ответ о том, как лучше всего обрабатывать точный запрос OP, см. В других ответах на этот вопрос
. В 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 для этого совета в комментариях.
Примерный метод был от барона Шварца, , первоначально опубликованного в Nabble , перефразированного и расширенного здесь.