ОБНОВЛЕНИЕ таблицы на основе той же таблицы

12

У меня есть таблица с описаниями продуктов, и у каждого описания продукта есть a product_idи a language_id. То , что я хочу сделать , это обновить все поля с language_idо 2равном том же , product_idгде language_idнаходится 1.

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

UPDATE
  products_description AS pd
SET 
  pd.products_seo = (
    SELECT
      pd2.products_seo
    FROM 
      products_description AS pd2
    WHERE
        pd2.language_id = 1
    AND pd2.products_id = pd.products_id
  )
WHERE
  pd.language_id <> 1

Есть ли «простой» способ обойти это ограничение в MySQL? Или какие-то "хитрости"? Я немного удивлен, что мой запрос не работает, как это кажется логичным.

nathangiesbrecht
источник

Ответы:

19

Это довольно рискованный бизнес, и я могу понять, почему. Это связано с тем, как MySQL обрабатывает подзапросы. Я написал об этом 22 февраля 2011 года: проблема с подзапросом MySQL

Выполнение JOIN с участием SELECT и подзапроса SELECT в порядке. С другой стороны, ОБНОВЛЕНИЯ и УДАЛЕНИЕ могут быть довольно смертельным приключением.

ПРЕДЛОЖЕНИЕ

Попробуйте рефакторинг запроса так, чтобы это было ВНУТРЕННЕЕ СОЕДИНЕНИЕ двух таблиц

UPDATE
    products_description pd INNER JOIN products_description pd2 ON
    (pd.products_id=pd2.products_id AND pd2.language_id=1 AND pd.language_id<>1)
SET pd.products_seo = pd2.products_seo;

Попробуйте!

RolandoMySQLDBA
источник
0

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

UPDATE tmContact 
INNER JOIN (
SELECT par.id, IF (LENGTH(contact.dynamicValues) > LENGTH(par.dynamicValues), contact.dynamicValues, par.dynamicValues) upd FROM tmContact par
INNER JOIN tmContact contact ON par.id = contact.linkCompanyId AND contact.linkCompanyId IS NOT NULL
WHERE contact.id IS NOT NULL AND contact.dynamicValues <>  par.dynamicValues AND LENGTH(contact.dynamicValues) > LENGTH(par.dynamicValues)
) input ON input.id = tmContact.id
SET tmContact.dynamicValues = upd;
Гальвани
источник
-3
  1. Сначала создайте таблицу view / temp с помощью оператора select
  2. Запустите запрос на обновление с внутренним соединением
Санкар Кодали
источник
2
Возможно, вы можете улучшить ответ с помощью некоторого примера кода?
ypercubeᵀᴹ