web-dev-qa-db-ja.com

同じテーブルに基づくUPDATEテーブル

製品の説明の表があり、各製品の説明にはproduct_idlanguage_idがあります。私がやりたいことは、language_id2であるすべてのフィールドを、product_idlanguage_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のこの制限を回避する「簡単な」方法はありますか?または「トリック」?論理的に見えるので、私のクエリが機能しないことに少し驚いています。

12

これはかなり危険なビジネスであり、その理由は理解できます。 MySQLがサブクエリを処理する方法に関係しています。 2011年2月22日にそれについて書きました: MySQLサブクエリの問題

SELECTとサブクエリSELECTを含むJOINの実行は問題ありません。逆に言えば、UPDATEとDELETEは、死に挑む冒険と言えるでしょう。

提案

クエリをリファクタリングして、2つのテーブルの内部結合になるようにします。

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;

試してみる !!!

20
RolandoMySQLDBA

まあ、これは私にとってはうまくいきませんでした。一致する行があったとしても、更新は行われませんでした。一時ファイルが使用されるように、サブクエリとして他のテーブルを作成する必要がありました。

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;
0
Galvani