[MySQL] UPDATE d'un champs à partir d'une autre table

UPDATE d'un champs à partir d'une autre table [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 28-08-2007 à 20:28:54    

bonjour,
 
je dois faire un update d'un champs mais la valeur se trouve dans une autre table. n'ayant jamais fait un update utilisant 2 tables en mysql je galère à faire cette requête, ce serait sympa si vous pouviez m'aider. merci d'avance :)  
 
tabA
id (clé primaire)
champsA1
champsA2
 
tabB
id (clé primaire)
user_id (clé étrangère de tabA)
champsB1
champsB2
 
j'aimerai récupérer les infos de champsB2 (si champsB1 = 1) et les insérer dans le champsA1.


Message édité par Fornium le 28-08-2007 à 20:29:23
Reply

Marsh Posté le 28-08-2007 à 20:28:54   

Reply

Marsh Posté le 29-08-2007 à 11:47:37    

Je sais que sous oracle c'est quelque chose du style :
 

Code :
  1. insert into tabA (champsA1)
  2. select champsB2  from tabB ;


 
Mais je n'ai jamais essayé avec mysql.


Message édité par turinatas le 29-08-2007 à 11:48:29
Reply

Marsh Posté le 29-08-2007 à 12:09:47    

Salut,  
si tes 2 tables ont une jointure, je crois que tu pense ecrire quelque chose comme ca :
 
UPDATE TabA INNER JOIN TabB ON (TabA.TonChampsA= TabB.TonChampsB) SET (TabA.champsA1= TabB.champsB2) WHERE TabB.champsA1 = 1
 
n'étant pas un pro de sql/mysql, je suis pas du tout sur que ca marche (surtout vis a vis du WHERE)

Reply

Marsh Posté le 29-08-2007 à 14:22:24    

je dirais plutôt :
 

Code :
  1. UPDATE tabA
  2. SET champA1 = (SELECT b.champsB2 FROM tabB b WHERE b.user_id = id AND b.champsB1 = 1)
  3. WHERE EXISTS (SELECT NULL FROM tabB b WHERE b.user_id = id AND b.champsB1 = 1)


Message édité par MagicBuzz le 29-08-2007 à 14:37:52
Reply

Marsh Posté le 29-08-2007 à 14:31:47    

mysql (depuis la version 4) supporte les jointures dans les sous-requetes sous à peu près toutes les formes:

Code :
  1. UPDATE tabA, tabB SET tabA.f2 = tabB.f2 WHERE tabA.f1 = tabB.f1 AND tabA.f3=0;
  2. -- ou
  3. UPDATE tabA INNER JOIN tabB ON tabA.f1 = tabB.f1 SET  tabA.f2 = tabB.f2 WHERE tabA.f3=0


Maintenant coté portabilité / lisibilité moi je suis pas fan :o
 
MagicBuzz> juste un reproche sur ta requete, si la sousrequete remonte plus d'un recordset c'est le plantage assuré

Reply

Marsh Posté le 29-08-2007 à 14:37:34    

je pars du principe effectivement que tabb.champsb1 est un compteur, donc unique pour une valeur de user_id donné. :jap:
 
mais si c'est pas unique, c'est très bien que ça plante, parcequ'on ne saura pas quoi écrire. je pense que les deux autres versions que tu as donné doivent merder sévère aussi dans ce cas là, car le comportement est imprévisible : il vaut mieux planter donc.
 
sinon, +1 pour les jointures dans les update. en soit, je trouve ça très bien que ça existe, mais la syntaxe diffère trop d'un sgbd à l'autre, et niveau lisibilité c'est pas toujours au point... :/

Reply

Marsh Posté le 29-08-2007 à 14:59:31    

plutôt que de planter et dans la mesure ou tu fais un exists pourquoi ne pas ajouter dans celui-ci un count(*)/having count=1 ?
Au moins ça planterait pas :o

Reply

Marsh Posté le 29-08-2007 à 15:03:17    

nan, le exists c'est pour éviter de coller "null" quand la jointure n'existe pas.
le having count=1 c'est sympa, mais du coup je vais mettre "n'importe laquelle" des différentes valeurs trouvées. ce n'est pas forcément acceptable comme solution.
et dans ce cas, je préfère obtenir une erreur, m'envoyant gentillement remettre de l'ordre dans mes données, plutôt que de passer comme papa dans maman, et pleurer dans 6 mois parceque je me rends compte que j'ai complètement pollué ma base avec des données incohérentes sans m'en rendre compte depuis des mois... :/

Reply

Marsh Posté le 29-08-2007 à 15:26:01    

MagicBuzz a écrit :

nan, le exists c'est pour éviter de coller "null" quand la jointure n'existe pas.


on est bien d'accord

MagicBuzz a écrit :

le having count=1 c'est sympa, mais du coup je vais mettre "n'importe laquelle" des différentes valeurs trouvées. ce n'est pas forcément acceptable comme solution.


Tu mets pas n'importe quelle valeur :/
Cela mettrait à jour uniquement les recordsets pour lesquels ils existent "une et une seule" valeur dans la table B pour le champ à mettre à jour.

MagicBuzz a écrit :

et dans ce cas, je préfère obtenir une erreur, m'envoyant gentillement remettre de l'ordre dans mes données, plutôt que de passer comme papa dans maman, et pleurer dans 6 mois parceque je me rends compte que j'ai complètement pollué ma base avec des données incohérentes sans m'en rendre compte depuis des mois... :/


Sauf que ce que je disais ne rajoute pas de bordel dans les données de la tableA. Mais il est vrai que cela ne permet pas de detecter celles de la tableB.
Après ça dépend de ce qu'on veut faire.

Reply

Marsh Posté le 29-08-2007 à 15:37:56    

ah oui effectivement (/me a du mal avec sa tête en ce moment, il bosse sur un gros projet au boulot et les trois neurrones sont à la limite de tourner en toast grillé)
 
m'enfin moi j'aime bien quand ça plante, comme ça quand tu corriges tu fais payer de la tma et tout le monde crois que t'es trop fort :D


Message édité par MagicBuzz le 29-08-2007 à 15:38:26
Reply

Marsh Posté le 29-08-2007 à 15:37:56   

Reply

Marsh Posté le 30-08-2007 à 15:30:16    

merci pour vous solutions les gars. en fait je me suis trompé sur le champs où je dois récupérer les valeurs :sweat:  
 
tabA
id (clé primaire)
champsA1
champsA2
champsA3
 
tabB
id (clé primaire)
user_id (clé étrangère de tabA)

champsB1
champsB2
 
je dois prendre les id de tabB (si champsB1 = 1 et champsB2 = A) et les insérer dans le champsA1 (si champsA2 = A et champsA3 = B)

Reply

Marsh Posté le 30-08-2007 à 15:34:02    

ben c'est la même requête, y'a que les noms qui changent [:spamafote]

Reply

Marsh Posté le 03-11-2008 à 11:34:42    

Bonjour, désolé de remonter cette vielle discussion mais j'ai un problème un peu similaire.
 
En fait j'ai créer une table avec 4 colonnes, qui prends les valeurs d'une autre table.
Malheureusement, j'ai oublié d'ajouté les valeurs correspondantes à la 4ème colonne, ce qui fait que j'ai que des null dans cette colonne.
 
Plutôt que de la supprimer et de la refaire, je cherche un moyen de l'updater pour y ajouter juste les valeurs de la 4eme colonne.
 
Voici comment j'ai essayé de faire :
 

Code :
  1. UPDATE target_information
  2. set target_name=(select last_name from targets)
  3. where target_id=(select target_id from targets)


 
Le message d'erreur : single row subquery return more than one row
 
Merci de votre aide
 

Reply

Marsh Posté le 03-11-2008 à 11:49:55    

Bon bah finalement j'ai trouvé, mais pas directement avec un update, en utilisant le merge into :
 

Code :
  1. Merge into target_information ti
  2. Using targets t
  3. on (ti.target_id=t.target_id)
  4. when matched then
  5. UPDATE
  6. set ti.target_name=t.last_name
  7. ;


Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed