web-dev-qa-db-fra.com

Table UPDATE basée sur la même table

J'ai un tableau avec des descriptions de produits, et chaque description de produit a un product_id et un language_id. Ce que je veux faire, c'est mettre à jour tous les champs avec un language_id de 2 pour être égal au même product_id où le language_id est 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.

12
nathangiesbrecht

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 sous-requêtes SELECT 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 !!!

20
RolandoMySQLDBA

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