Patrice Ferlet
Patrice Ferlet
Créateur de ce blog.
Publié le nov. 20, 2009 Temps de lecture: 3 min

Me suivre sur Mastodon

MYSQL Update via SELECT

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 !

comments powered by Disqus