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


12

製品の説明を含む表があり、各製品の説明にはとがproduct_idありますlanguage_id。私がやりたいのは、すべてのフィールドをで更新し、language_idがである場所2と同じになるようにすることです。product_idlanguage_id1

これまでのところ、次のクエリを試しましたが、テーブルがサブクエリでも使用されているテーブルを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のこの制限を回避する「簡単な」方法はありますか?それとも「トリック」ですか?論理的に思えるので、クエリが機能しないことに少し驚いています。

回答:


19

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

SELECTおよびサブクエリSELECTを含むJOINの実行は問題ありません。反対に、UPDATEとDELETEはかなり致命的な冒険になる可能性があります。

提案

2つのテーブルのINNER JOINになるようにクエリをリファクタリングしてみてください

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;

試してみる !!!


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. 最初にselectステートメントでビュー/一時テーブルを作成します
  2. 内部結合で更新クエリを実行する

2
おそらく、あなたはいくつかのサンプルコードで答えを改善できますか?
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.