MYSQL Update via SELECT

20/11/2009

Ce coup-ci j’ai cherché longtemps… et j’ai trouvé! Le problème était de corriger une table mal foutue: il fallait que j’update une table en assignant des valeur dans un champs provenant d’un select sur la même table. Attendez, je vais vous montrer le problème.

Imaginons une table de ce genre “BandeDessinée”:

  • id (int auto_increment)
  • titre (varchar 255)
  • type (varchar 255)

Or voilà, “type” est un varchar (255) qui contient un type de bande dessinée. On décide de faire une table qui contient les types (bdtypes):

  • id (int auto_increment)
  • type (varchar 255)

Maintenant, le but c’est de faire la jointure entre les deux tables. On va ajouter un champs dan la table des bande dessinées:

  • id (int auto_increment)
  • titre (varchar 255)
  • type (varchar 255)
  • type_id (int)

Comme ça, quand ce sera rempli, je pourrais supprimer le champs “type” qui ne me servira à rien.

Dans la table de types, j’ai des valeurs: commics, épique, histoire, action, romance…

Et dans le champs de type de la table de bande dessinée… j’ai un peu n’importe quoi… mais en gros j’ai presque les même noms (à quelques majuscules près).

Je me dis alors: “go, un vieux update avec un select et ça va passer tout seul”. Et bien non ! Voilà sur quoi j’étais parti:

<code> update into bande_dessinee bd set bd.type_id = ( SELECT distinct ty.id from bdtypes ty inner join bande_dessinee bd1 on ty.type like concat(“%”,bd1.type,“%”) where bd1.id = bd.id ); </code>

Tu parles… pourtant la requête de select est bonne (cherchez pas, même si j’ai foiré mon code dans le billet, ce qui est fort possible parce que je ne bosse pas sur une table si simple de bande dessinées, mais sur une table un peu plus violente… je vous assure, et je vous jure que mon select passait parfaitement tant qu’il n’était pas dans le update set)

En gros, le select imbriqué refuse de voir l’alias “bd”. ET j’aurais beau sortir le WHERE l’erreur reste la même…

Bon, je vais pas tortiller pendant 3 ans, je vous donne la solution.

<code> UPDATE bande_dessinee bd JOIN bdtypes ty on bd.type like concat (‘%’,ty.type,‘%’) set bd.type_id = ty.id </code>

Grosso modo, on fait une jointure entre “bande_dessinee” et “bdtypes” pour récupérer la valeur qui colle les deux tables. Cette valeur étant “bdtypes.type vers bande_dessinee.type”. La jointure permet d’une part de récupérer la ligne à modifier mais aussi les valeurs à récupérer dans la table jointe. C’est en fait un peu plus puissant qu’un select imbriqué :)

On récupère alors bdtype.id (alias ty.id) que l’on insert dans bande_dessinee.

Je peux vous assurer que quand ça a marché, j’ai fait un beau sourir à mon écran de PC !

Ça peut vous intéresser aussi


Sun rachète MySQL

On vient de l’apprendre, Sun rachète Mysql! C’est ...


Récupération de MySQL cassé

Je viens d’exploser, sans trop savoir pourquoi, ma base ...


MySQL Failed to CREATE FUNCTION

Ce matin, grosse peur et surtout gros coup de stress ...


Poste de développement PHP sous Fedora

Linux est un système parfait pour développer. Simple d’installation,...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Jikoo - 04/12/2011

Merci de cette aide précieuse : J’ai galéré pendant des heures. Merci beaucoup pour l’explication. C’est très clair.

Julien - 14/09/2012

Merci aussi!

Noel Flantier - 05/02/2014

Vous arrive-t-il de prendre des cours de Français ? Ceci est une requete SELECT imbriquée dans un UPDATE. Luc, je que l’homme de la situation. Je que dossier bleu et vous sur une centaine de tableaux très clairs. Vous semaine prochaine sans faute. Je tellement sur vous ! Je clair Luc, ne pas ?

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.