Table UPDATE basée sur la même table

12

J'ai un tableau avec des descriptions de produits, et chaque description de produit a un product_idet un language_id. Ce que je veux faire est de mettre à jour tous les champs avec language_iddes 2être égale à la même product_idlanguage_idest 1.

Jusqu'à présent, j'ai essayé la requête suivante, mais je reçois des erreurs indiquant que MySQL ne veut pas mettre à jour une table où la table est également utilisée dans la sous-requête.

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

Existe-t-il un moyen "simple" de contourner cette limitation dans MySQL? Ou des "trucs"? Je suis un peu surpris que ma requête ne fonctionne pas, car cela semble logique.

nathangiesbrecht
la source

Réponses:

19

C'est une affaire plutôt risquée et je peux comprendre pourquoi. Cela a à voir avec la façon dont MySQL traite les sous-requêtes. J'ai écrit à ce sujet le 22 février 2011: problème avec la sous-requête MySQL

La réalisation de JOIN impliquant des SELECT et des SELECT de sous-requête est OK. À l'inverse, UPDATEs et DELETE peuvent être une aventure plutôt défiante.

SUGGESTION

Essayez de refactoriser la requête afin qu'elle soit une jointure interne de deux tables

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;

Essaie !!!

RolandoMySQLDBA
la source
0

Eh bien, cela n'a pas fonctionné pour moi, la mise à jour ne s'est tout simplement pas produite même s'il y avait des lignes correspondantes. Ce que je devais faire était de créer l'autre table en tant que sous-requête afin d'utiliser un fichier temporaire.

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;
Galvani
la source
-3
  1. Créez d'abord la table view / temp avec l'instruction select
  2. Exécuter une requête de mise à jour avec jointure interne
Sankar Kodali
la source
2
Peut-être pouvez-vous améliorer la réponse avec un exemple de code?
ypercubeᵀᴹ