Error code 1093 mysql

I have a table story_category in my database with corrupt entries. The next query returns the corrupt entries: SELECT * FROM story_category WHERE category_id NOT IN ( SELECT DISTINCT catego...

Update: This answer covers the general error classification. For a more specific answer about how to best handle the OP’s exact query, please see other answers to this question

In MySQL, you can’t modify the same table which you use in the SELECT part.
This behaviour is documented at:
http://dev.mysql.com/doc/refman/5.6/en/update.html

Maybe you can just join the table to itself

If the logic is simple enough to re-shape the query, lose the subquery and join the table to itself, employing appropriate selection criteria. This will cause MySQL to see the table as two different things, allowing destructive changes to go ahead.

UPDATE tbl AS a
INNER JOIN tbl AS b ON ....
SET a.col = b.col

Alternatively, try nesting the subquery deeper into a from clause …

If you absolutely need the subquery, there’s a workaround, but it’s
ugly for several reasons, including performance:

UPDATE tbl SET col = (
  SELECT ... FROM (SELECT.... FROM) AS x);

The nested subquery in the FROM clause creates an implicit temporary
table
, so it doesn’t count as the same table you’re updating.

… but watch out for the query optimiser

However, beware that from MySQL 5.7.6 and onward, the optimiser may optimise out the subquery, and still give you the error. Luckily, the optimizer_switch variable can be used to switch off this behaviour; although I couldn’t recommend doing this as anything more than a short term fix, or for small one-off tasks.

SET optimizer_switch = 'derived_merge=off';

Thanks to Peter V. Mørch for this advice in the comments.

Example technique was from Baron Schwartz, originally published at Nabble, paraphrased and extended here.

Дата: 25.10.2013

Автор: Василий Лукьянчиков , vl (at) sqlinfo (dot) ru

В статье рассмотрены ошибки, возникающие из-за ограничений сервера MySQL на выполнение некоторых видов подзапросов. Даны рекомендации по их исправлению с примерами. Материал ориентирован на новичков.

MySQL error 1093

В MySQL нельзя изменять данные и одновременно делать выборку из той же таблицы в подзапросе. Запросы вида

DELETE FROM t WHERE col = (SELECTFROM t …);
UPDATE t … WHERE col = (SELECTFROM t …);
{INSERT|REPLACE} INTO t (SELECTFROM t …);

приведут к ошибке

ERROR 1093 (HY000): You can‘t specify target table ‘t‘ for update in FROM clause.

Есть два варианта решения проблемы:

1. Универсальный способ, рекомендуемый в документации, — использовать вложенный подзапрос.

DELETE FROM t WHERE col = (SELECT * FROM (SELECTFROM t…) AS t1);
UPDATE t … WHERE col = (SELECT * FROM (SELECTFROM t…) AS t1);
{INSERT|REPLACE} INTO t (SELECT * FROM (SELECTFROM t…) AS t1);

В этом случае подзапрос к изменяемой таблице оказывается в части FROM и материализуется во временную таблицу в начале выполнения запроса. Т.о. при обновлении чтение данных будет идти из временной таблицы, а не из той, которая обновляется.

2. Для запросов UPDATE и DELETE можно использовать многотабличную форму. Например, для UPDATE запрос выше примет вид:

UPDATE t, (SELECTFROM t …) t1 … WHERE t.col=t1.col;

По сути это тот же метод, что и предыдущий — подзапрос переносится в часть перечисления таблиц. Но кроме чуть более компактной записи многотабличная форма операторов UPDATE/DELETE в некоторых случаях позволяет вообще обойтись без подзапроса.

Примеры:

  • мы хотим удалить из первой таблицы строки, не имеющие соответствия (по id) во второй.

    DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

    Для сравнения через подзапрос:

    DELETE FROM t1 WHERE id IN (SELECT * FROM (SELECT t1.id FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL) as t_x);

  • удалить из таблицы дубликаты (строки с одинаковыми значениями поля col) с меньшим id

    DELETE t1 FROM t t1 JOIN t t2
    ON t1.col = t2.col AND t1.id < t2.id;

    через подзапрос

    DELETE t FROM t LEFT JOIN (SELECT max(id) as id, col FROM t GROUP BY col) t1 USING(id) WHERE t1.id IS NULL;

  • а вот задача пометить важными статьи авторов, имеющих более 10 публикаций, без подзапроса не решается:

    UPDATE articles SET important=1 WHERE author IN (SELECT * FROM (SELECT author FROM articles GROUP BY 1 HAVING count(*)>10) t);

    или

    UPDATE articles, (SELECT author FROM articles GROUP BY 1 HAVING count(*)>10) t SET important=1  WHERE author = t.author;

  • в завершение рассмотрим пример, когда подзапрос находится в части SET. Например, для строк с id>10 мы хотим установить значение поля col равное значению этого поля для строки с id равным 2.

    UPDATE t as t1 JOIN t as t2 ON t2.id=2 SET t1.col = t2.col WHERE t1.id > 10;

    через подзапрос

    UPDATE t
        SET col = (SELECT * FROM (SELECT col FROM t WHERE id = 2) AS t1)
        WHERE id = >10;

MySQL error 1235

В MySQL не реализована возможность использования IN/ALL/ANY/SOME вместе с подзапросом, содержащим LIMIT. Попытка выполнить такой запрос приведет к ошибке:

mysql> SELECT * FROM t1
    ->   WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1);
ERROR 1235 (42000): This version of MySQL doesn‘t yet support
 ‘
LIMIT & IN/ALL/ANY/SOME subquery

Данное ограничение обходится путем переписывания запроса через JOIN с нужным подзапросом. Например:

SELECT * FROM t1 WHERE t1.col1 IN (SELECT col2 FROM t2 WHERE x);

можно переписать как

SELECT * FROM t1 JOIN (SELECT DISTINCT col2 FROM t2 WHERE x) t ON t1.col1=t.col2;

Если t2.col2 — уникальный ключ, то DISTINCT не потребуется и от подзапроса можно избавиться:

SELECT * FROM t1 JOIN t2 ON t1.col1=t.col2 WHERE t2.x;

На практике IN подзапросы более распространены и в большинстве случаев указанного правила будет достаточно. Некоторые виды ALL/ANY подзапросов могут потребовать более сложных преобразований, но переписать через JOIN можно любой их них.

Например, мы хотим найти страны в Европе, у которых каждый из трех самых крупных городов имеют население свыше миллиона. Если бы не запрет на использование LIMIT в ALL подзапросах, то решением было:

SELECT name FROM country WHERE continent=‘Europe’ AND
1000000 < ALL (SELECT population FROM city WHERE countrycode=code OREDR BY 1 DESC LIMIT 3);

через JOIN данный запрос примет вид:

SELECT country.name FROM country JOIN city ON countrycode=code
WHERE continent=‘Europe’ AND city.population>1000000
GROUP BY 1 HAVING(count(*)>2);

Замечание: Использовать вложенный подзапрос при mysql error 1235 является плохой идеей:

1. этот прием сработает только в случае независимых подзапросов;

2. на старых версиях (до MariaDB5.3/MySQL5.6) будет иметь худшую производительность, а в новых оптимизатор сам перепишет запрос через JOIN

P.S. Если после прочтения статьи ваш вопрос с MySQL Error 1093 или 1235 остался нерешенным, то задавайте его на форуме SQLinfo

Дата публикации: 25.10.2013

© Все права на данную статью принадлежат порталу SQLInfo.ru. Перепечатка в интернет-изданиях разрешается только с указанием автора и прямой ссылки на оригинальную статью. Перепечатка в бумажных изданиях допускается только с разрешения редакции.

Stuck with MySQL error code 1093? We can help you fix it.

This error is mainly related to the subqueries.

At Bobcares, we often get requests to fix MySQL errors, as a part of our Server Management Services.

Today, let’s see how our Support Engineers fix MySQL Error Code 1093 for our customers.

Why MySQL error code 1093?

While dealing with MySQL, we may encounter some errors.

Today, we shall discuss MySQL error 1093 and see how we fix it.

This MySQL error code is mainly related to subqueries. It appears while updating or deleting a table, and while building a subquery for that using the same table.

How we fix it?

Recently, one of our customers approached us with a request to fix an error like the one shown below, which he was getting while updating a table.

MySQL error code 1093

So, our Engineers checked in detail and found that he was using a subquery build with the same table which he wanted to update.

So, we deleted the reference of the table to update from subquery and this fixed the error.

Also, we handled a situation where a customer approached us with the same MySQL error code 1093.

He said this error appeared while trying to delete a table using a query as given below:

DELETE FROM table_name where column_name IN (SELECT column_name FROM table_name WHERE column_name &gt; 10);

We changed the query as below because the customer is trying to delete the rows from the same data source which a subquery refers to, and that cannot be deleted.

DELETE FROM table_name where column_name IN ( SELECT * FROM (SELECT column_name FROM table_name WHERE column_name &gt; 10) AS X) ;

Finally, this fixed the error.

[Need more assistance to fix the MySQL Error code 1093?- We’re available 24/7.]

Conclusion

In short, this error can be fixed by deleting the reference of the table to update from the subquery. Also, we saw how our Support Engineers find fix for this MySQL error.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = «owonCMyG5nEQ0aD71QM»;

Содержание

  1. MySQL error 1093 и 1235
  2. MySQL error 1093
  3. MySQL error 1235
  4. MySQL error code 1093 – How we tackle it
  5. Why MySQL error code 1093?
  6. How we fix it?
  7. Conclusion
  8. PREVENT YOUR SERVER FROM CRASHING!
  9. Не возможно использовать для обновления таблицу, в которой производишь выборку
  10. Вот примеры запросов
  11. По отдельности все работает
  12. Решение
  13. UPD: Создадим процедуру и евент для этого события
  14. Комментарии
  15. Ошибка MySQL 1093 — невозможно указать целевую таблицу для обновления в предложении FROM
  16. 16 ответы
  17. Ошибка MySQL 1093 — невозможно указать целевую таблицу для обновления в предложении FROM

MySQL error 1093 и 1235

Автор: Василий Лукьянчиков , vl (at) sqlinfo (dot) ru

В статье рассмотрены ошибки, возникающие из-за ограничений сервера MySQL на выполнение некоторых видов подзапросов. Даны рекомендации по их исправлению с примерами. Материал ориентирован на новичков.

MySQL error 1093

В MySQL нельзя изменять данные и одновременно делать выборку из той же таблицы в подзапросе. Запросы вида

Есть два варианта решения проблемы:

1. Универсальный способ, рекомендуемый в документации, — использовать вложенный подзапрос.

В этом случае подзапрос к изменяемой таблице оказывается в части FROM и материализуется во временную таблицу в начале выполнения запроса. Т.о. при обновлении чтение данных будет идти из временной таблицы, а не из той, которая обновляется.

2. Для запросов UPDATE и DELETE можно использовать многотабличную форму. Например, для UPDATE запрос выше примет вид:

По сути это тот же метод, что и предыдущий — подзапрос переносится в часть перечисления таблиц. Но кроме чуть более компактной записи многотабличная форма операторов UPDATE/DELETE в некоторых случаях позволяет вообще обойтись без подзапроса.

    мы хотим удалить из первой таблицы строки, не имеющие соответствия (по id) во второй.

MySQL error 1235

В MySQL не реализована возможность использования IN/ALL/ANY/SOME вместе с подзапросом, содержащим LIMIT. Попытка выполнить такой запрос приведет к ошибке:

Данное ограничение обходится путем переписывания запроса через JOIN с нужным подзапросом. Например:
SELECT * FROM t1 WHERE t1.col1 IN ( SELECT col2 FROM t2 WHERE x ) ;
можно переписать как
SELECT * FROM t1 JOIN ( SELECT DISTINCT col2 FROM t2 WHERE x ) t ON t1.col1=t.col2;
Если t2.col2 — уникальный ключ, то DISTINCT не потребуется и от подзапроса можно избавиться:
SELECT * FROM t1 JOIN t2 ON t1.col1=t.col2 WHERE t2.x;

На практике IN подзапросы более распространены и в большинстве случаев указанного правила будет достаточно. Некоторые виды ALL/ANY подзапросов могут потребовать более сложных преобразований, но переписать через JOIN можно любой их них.

Например, мы хотим найти страны в Европе, у которых каждый из трех самых крупных городов имеют население свыше миллиона. Если бы не запрет на использование LIMIT в ALL подзапросах, то решением было:

через JOIN данный запрос примет вид:

Замечание: Использовать вложенный подзапрос при mysql error 1235 является плохой идеей:
1. этот прием сработает только в случае независимых подзапросов;
2. на старых версиях (до MariaDB5.3/MySQL5.6) будет иметь худшую производительность, а в новых оптимизатор сам перепишет запрос через JOIN

Источник

MySQL error code 1093 – How we tackle it

Stuck with MySQL error code 1093? We can help you fix it.

This error is mainly related to the subqueries.

At Bobcares, we often get requests to fix MySQL errors, as a part of our Server Management Services.

Today, let’s see how our Support Engineers fix MySQL Error Code 1093 for our customers.

Why MySQL error code 1093?

While dealing with MySQL, we may encounter some errors.

Today, we shall discuss MySQL error 1093 and see how we fix it.

This MySQL error code is mainly related to subqueries. It appears while updating or deleting a table, and while building a subquery for that using the same table.

How we fix it?

Recently, one of our customers approached us with a request to fix an error like the one shown below, which he was getting while updating a table.

So, our Engineers checked in detail and found that he was using a subquery build with the same table which he wanted to update.

So, we deleted the reference of the table to update from subquery and this fixed the error.

Also, we handled a situation where a customer approached us with the same MySQL error code 1093.

He said this error appeared while trying to delete a table using a query as given below:

We changed the query as below because the customer is trying to delete the rows from the same data source which a subquery refers to, and that cannot be deleted.

Finally, this fixed the error.

[Need more assistance to fix the MySQL Error code 1093?- We’re available 24/7.]

Conclusion

In short, this error can be fixed by deleting the reference of the table to update from the subquery. Also, we saw how our Support Engineers find fix for this MySQL error.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

Источник

Не возможно использовать для обновления таблицу, в которой производишь выборку

Понадобилось ежесуточно высчитывать размер шрифта для оформления вывода жанров на Кинсбурге. И столкнулся с проблемой, что нельзя выбирать данные из таблицы, которая участвует в обновлении данных.

Вот примеры запросов

Попробуем вложенный селект:

По отдельности все работает

Выводим «размер шрифта»:

Обновляем поле с размером шрифта:

Решение

Погуглив, и поломав голову с disc’ом, я пришел к следующему решению, представленное ниже.

Я решил выделить вычисление процента в переменную @percent, далее создал вьюху для таблицы «categories» и жойню таблицу с вьюхой:

Вот и все, приятного манокурения 🙂

UPD: Создадим процедуру и евент для этого события

Комментарии

Adw0rd, Насколько я понимаю что после выполнения данной процедуры, что после желаемого изначально UPDATE, у нас будет стопицот категорий, с одним и тем же значением size .
Внимание вопрос: «Зачем хранить одно и то же значение в 9342423 экземплярах? Как же нормализация?»

ИМХО: по крону раз в те-же сутки меняем значение «.categories_cloud <
font-size. » в CSS файле и не усложняем зря жизнь себе и БД 🙂

Ну а так да, вполне себе приятное решение.

Насколько я понимаю что после выполнения данной процедуры, что после желаемого изначально UPDATE, у нас будет стопицот категорий, с одним и тем же значением `size`

Нет, не будет, я же проверяю сначала, прежде чем публиковать. 😉

Зачем хранить одно и то же значение в 9342423 экземплярах? Как же нормализация?

вот что получается

Никаких «9342423 экземплярах» 😉

И вот такое облако получаем:

Нет, не будет, я же проверяю сначала, прежде чем публиковать. 😉

Хм. Просто запрос:

У меня лично выдает только одно значение — 1.2500(Как я понимаю для последнего столбца с id 19 (MySQL5). Или я что-то недопонимаю?

ИМХО все равно данные размера как таковые к категориям особого отношения не имеют, они грубо говоря связь облака тегов с категориями, да и юзаются они ведь только в нем, не так ли?

Поэтому можно было бы сделать таблицу:

Ну и в ней собственно все их(значения) хранить.

да, именно этот запрос сделает всем строкам один результат, но этот запрос только для теста, посмотри внимательно процедуру, там этот кусок кода:

вынесен в отдельную переменную @percent и все работает наура, для всех строк

ИМХО все равно данные размера как таковые к категориям особого отношения не имеют, они грубо говоря связь облака тегов с категориями, да и юзаются они ведь только в нем, не так ли?

Не согласен, зачем мне делать доп. таблицу, если эти данные необходимы для генерации облака (титл, урл, размер)?

Я считаю это лишним.

Поэтому можно было бы сделать таблицу: Ну и в ней собственно все их(значения) хранить.

С тем же успехом можно было отделить «count» в другую таблицу.

count имеет отношение к категориям,
size имеет отношение исключительно к облакам и нефиг ему делать в основной таблице.

Впрочем на вкус и цвет товарищей нет. Проехали 🙂

Ну да я это понял, просто меня переклинило на первом запросе, стормозил признаю.

P.S.
Впринципе вполне логично, что они гененрят только одну строку ибо MAX, MIN это же агрегатные функции GROUP BY.
Можно было бы заменить аццким запросом:

Твой вариант лучше безусловно прозрачнее и быстрее, мне просто занятся нечем пока футурама скачивается.

`size` имеет отношение исключительно к облакам и нефиг ему делать в основной таблице.

Ну смотри, для генерации облака нам нужно помимо «размера» еще «имя жанра» и «ссылка, либо ид жанра», так?

Тогда логично чтобы они были в одной таблице, чтобы не делать лишнего жойна, так?

Тогда куда мне всунуть «размер»? Или ты мне предлагаешь одинаковые данные хранить в двух таблицах?

Источник

Ошибка MySQL 1093 — невозможно указать целевую таблицу для обновления в предложении FROM

У меня есть таблица story_category в моей базе данных с поврежденными записями. Следующий запрос возвращает поврежденные записи:

Я пытался удалить их, выполнив:

Но получаю следующую ошибку:

# 1093 — Вы не можете указать целевую таблицу ‘story_category’ для обновления в предложении FROM

Как я могу это преодолеть?

задан 05 сен ’08, 08:09

Похоже, что запрос функции в системе отслеживания ошибок MySQL находится здесь: не может обновить таблицу и выбрать из той же таблицы в подзапросе — Ben Creasy

16 ответы

Обновление: этот ответ охватывает общую классификацию ошибок. Более конкретный ответ о том, как лучше всего обрабатывать точный запрос OP, см. В других ответах на этот вопрос.

В MySQL вы не можете изменять ту же таблицу, которую используете в части SELECT.
Это поведение задокументировано по адресу: http://dev.mysql.com/doc/refman/5.6/en/update.html

Может быть, ты можешь просто присоединиться к столу к себе

Если логика достаточно проста, чтобы изменить форму запроса, потеряйте подзапрос и присоедините таблицу к самой себе, используя соответствующие критерии выбора. Это заставит MySQL рассматривать таблицу как две разные вещи, позволяя вносить деструктивные изменения.

В качестве альтернативы попробуйте вложить подзапрос глубже в предложение from .

Если вам абсолютно необходим подзапрос, есть обходной путь, но он уродлив по нескольким причинам, включая производительность:

Вложенный подзапрос в предложении FROM создает неявная временная таблица, поэтому она не считается той же таблицей, которую вы обновляете.

. но остерегайтесь оптимизатора запросов

Однако имейте в виду, что от MySQL 5.7.6 и далее оптимизатор может оптимизировать подзапрос и по-прежнему выдавать вам ошибку. К счастью, optimizer_switch переменную можно использовать для отключения этого поведения; хотя я не мог рекомендовать делать это как нечто большее, чем краткосрочное исправление или для небольших разовых задач.

Благодаря Питер В. Мёрч за этот совет в комментариях.

Пример техники был от барона Шварца, первоначально опубликовано на Nabble, перефразировано и расширено здесь.

Источник

Ошибка MySQL 1093 — невозможно указать целевую таблицу для обновления в предложении FROM

У меня есть таблица story_category в моей базе данных с поврежденными записями. Следующий запрос возвращает поврежденные записи:

Я пытался удалить их, выполнив:

Но получаю следующую ошибку:

#1093 — You can’t specify target table ‘story_category’ for update in FROM clause

Как я могу это преодолеть?

Обновление: этот ответ охватывает общую классификацию ошибок. Более конкретный ответ о том, как лучше всего обрабатывать точный запрос OP, см. В других ответах на этот вопрос.

В MySQL вы не можете изменять ту же таблицу, которую используете в части SELECT.
Это поведение задокументировано по адресу: http://dev.mysql.com/doc/refman/5.6/en/update.html.

Может быть, вы можете просто присоединиться к столу к себе

Если логика достаточно проста, чтобы изменить форму запроса, потеряйте подзапрос и присоедините таблицу к самой себе, используя соответствующие критерии выбора. Это заставит MySQL рассматривать таблицу как две разные вещи, позволяя вносить деструктивные изменения.

В качестве альтернативы попробуйте вложить подзапрос глубже в предложение from .

Если вам абсолютно необходим подзапрос, есть обходной путь, но он уродлив по нескольким причинам, включая производительность:

Вложенный подзапрос в предложении FROM создает неявную временную таблицу , поэтому он не считается той же таблицей, которую вы обновляете.

. но остерегайтесь оптимизатора запросов

Однако имейте в виду , что начиная с MySQL 5.7.6 и выше оптимизатор может оптимизировать подзапрос и по-прежнему выдавать вам ошибку. К счастью, optimizer_switch переменную можно использовать для отключения этого поведения; хотя я не мог рекомендовать делать это как нечто большее, чем краткосрочное исправление или для небольших разовых задач.

Спасибо Peter V. Mørch за этот совет в комментариях.

Пример техники был от Baron Schwartz, первоначально опубликован в Nabble , перефразированный и расширенный здесь.

Источник

Получил такую ошибку при выполнении SQL запроса со вложенным подзапросом следующего вида.

UPDATE table_name
	SET col = (SELECT col FROM table WHERE id = :x)
	WHERE id = :y

Причина ошибки довольно проста, MySQL не даст обновить ту же самую таблицу, из которой происходит чтение. Проблему можно решить парой способов.

Способ 1. C использованием JOIN, предпочтительный.

UPDATE table_name t1
	JOIN table_name t2 ON t2.id = :x
	SET t1.val = t2.val
	WHERE t1.id = :y

Способ 2. С использованием SELECT FROM SELECT. В этом случае для результата внутреннего подзапроса будет создана временная таблица, и обновление пройдет успешно.

UPDATE table_name
	SET col = (SELECT col FROM (SELECT col FROM table WHERE id = :x) AS t2)
	WHERE id = :y

Примечание. Если с SELECT FROM SELECT всё понятно, то многие не знают что JOIN также работает при запросах с оператором DELETE. Возьмём к примеру таблицу (id, name), где id — уникальный идентификатор, name — название, и возникла задача удалить записи с дубликатами названий. Решить проблему можно таким вот запросом.

DELETE t1
	FROM table_name t1
	JOIN table_name t2 ON t2.name = t1.name AND t2.id < t1.id

If you are a developer or DB administrator it’s a common situation that you need to update MySQL table , for example to set user statuses depending on Id column.

Let’s say that we need to unvalidate users with Id < 100. If you try to run the following query:

update Users set Valid = 0
where Id in (
  select Id from Users where Id < 100
)

You’ll get the error message:

#1093 — You can’t specify target table ‘xxx’ for update in FROM clause

Explanation

MySQL doesn’t allow updating the table you are already using in an inner select as the update criteria.

Many other database engines has support for this feature, but MySQL doesn’t and you need to workaround the limitation. 

Solution

So, how to update the same table in MySQL? 

The trick is to use a subquery, i.e. to update a table while selecting from it itself in a subquery.

update Users set Valid = 0
where Id in (
  select Id from (
    select Id from Users where Id < 100
  ) as t
)

This is basically the same question as above, except the inner select is wrapped inside another select.

The alias in this query is important because it tells MySQL to create a temporary table from this select query and it may be used as the source criteria for the update statement.

Consider that you shouldn’t use select * from table in the subquery, but rather particular field due to perfrormance issues.

27 июля 2009 г.

MySQL

Не возможно использовать для обновления таблицу, в которой производишь выборку

mysql-logo

Понадобилось ежесуточно высчитывать размер шрифта для оформления вывода жанров на Кинсбурге. И столкнулся с проблемой, что нельзя выбирать данные из таблицы, которая участвует в обновлении данных.

Вот примеры запросов

Пробуем в лоб:

update `categories` set `size` = (`count` / ((max(`count`) - min(`count`)) / 10));
ERROR 1111 (HY000): Invalid use of group function

Попробуем вложенный селект:

update `categories` set `size` = (select (`count` / ((max(`count`) - min(`count`)) / 10)) from `categories`);
ERROR 1093 (HY000): You can't specify target table 'categories' for update in FROM clause

Попробуем жоин:

update `categories` as `c1` 
JOIN `categories` as `c2` 
using(`category_id`) 
set `c1`.`size` = (`c2`.`count` / ((max(`c2`.`count`) - min(`c2`.`count`)) / 10));

ERROR 1111 (HY000): Invalid use of group function

По отдельности все работает

Выводим «размер шрифта»:

select (`count` / ((max(`count`) - min(`count`)) / 10)) from `categories`;
+--------------------------------------------------------+
| (`count` / ((max(`count`) - min(`count`)) / 10))     |
+--------------------------------------------------------+
|                                             3.47826087 |
+--------------------------------------------------------+
1 row in set (0.00 sec)

Обновляем поле с размером шрифта:

update `categories` set `size` = 3.47826087;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 21  Changed: 0  Warnings: 0

Решение

Погуглив, и поломав голову с disc’ом, я пришел к следующему решению, представленное ниже.

Я решил выделить вычисление процента в переменную @percent, далее создал вьюху для таблицы «categories» и жойню таблицу с вьюхой:

-- создаем коэффициент деления
set @percent = (select (max(`count`) - min(`count`)) / 10 from `categories`);

-- создаем вьюху
create view `categories_view` as select `category_id`, `count` from `categories`;

-- жойним таблицу и вьюху, обновляя данные
update `categories` as `c`
join `categories_view` as `cv`
using(`category_id`)
set `c`.`size` = `cv`.`count` / @percent;

Вот и все, приятного манокурения :)

UPD: Создадим процедуру и евент для этого события

/* Создаем вьюху и процедуру для установки размеров шрифта */
use kinsburg;

/* создаем вьюху */
CREATE VIEW `categories_view` AS SELECT `category_id`, `count` FROM `categories`;

/* создаем процедуру */
delimiter //
DROP PROCEDURE IF EXISTS `updateCategorySize`//
CREATE PROCEDURE `updateCategorySize` ()
BEGIN
    /* создаем коэффициент деления */
    SET @percent = (SELECT (max(`count`) - min(`count`)) / 10 FROM `categories`);
    /* жойним таблицу и вьюху, обновляя данные */
    UPDATE `categories` AS `c` JOIN `categories_view` AS `cv` USING(`category_id`) SET `c`.`size` = `cv`.`count` / @percent;
END//
delimiter ;

/* создаем евент для вызова процедуры раз в сутки */
CREATE
    DEFINER = kinsburg@localhost
    EVENT `updateCategorySizeEvent`
    ON SCHEDULE
      EVERY 1 DAY
    DO
      CALL updateCategorySize; 

Let us first create a table −

mysql> create table DemoTable1597
   -> (
   -> Marks int
   -> );
Query OK, 0 rows affected (0.69 sec)

Insert some records in the table using insert command −

mysql> insert into DemoTable1597 values(45);
Query OK, 1 row affected (0.21 sec)
mysql> insert into DemoTable1597 values(59);
Query OK, 1 row affected (0.24 sec)
mysql> insert into DemoTable1597 values(43);
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable1597 values(85);
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable1597 values(89);
Query OK, 1 row affected (0.12 sec)

Display all records from the table using select statement −

mysql> select * from DemoTable1597;

This will produce the following output −

+-------+
| Marks |
+-------+
|    45 |
|    59 |
|    43 |
|    85 |
|    89 |
+-------+
5 rows in set (0.00 sec)

Here is the query to remove ERROR 1093 (HY000). We are deleting the lowest value here −

mysql> delete from DemoTable1597
   -> where Marks=(
   -> select lowestMarks from ( select min(Marks) as lowestMarks from DemoTable1597 ) as deleteRecord
   -> ) limit 1;
Query OK, 1 row affected (0.11 sec)

Let us check the table records once again −

mysql> select * from DemoTable1597;

This will produce the following output −

+-------+
| Marks |
+-------+
|    45 |
|    59 |
|    85 |
|    89 |
+-------+
4 rows in set (0.00 sec)

Понравилась статья? Поделить с друзьями:
  • Error code 1073741795
  • Error code 1292 truncated incorrect double value
  • Error code 1292 mysql
  • Error code 1285
  • Error code 1073741790