IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

UPDATE conditionnel entre 2 tables


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut UPDATE conditionnel entre 2 tables
    Bonjour,


    J'ai deux tables T1 et T2 ayant -à peu près-la même structure

    T1
    clé,C1,C2,C3

    T2
    clé,C1,C2,C3

    les champs c1,c2 et C3 ont par défaut la valeur '555', mais peuvent contenir d'autres valeurs < 1

    Pour parler des champs c1,c2 et C3 j'utilise Ci

    Je dois donc parcourir T2 et T1
    Si je trouve t1.cle=t2.cle alors je mets les données à jour dans t1 de la manière suivante:
    • si (T2.Ci<> '555' et T1.Ci='555' ) alors (update t1 set T1.Ci= T2.Ci)
    • Si (si (T2.Ci<> '555' et T1.Ci<> '555') et (T2.Ci<T1.Ci)) alors (update t1 set T1.Ci= T2.Ci)
    • Enfin je supprime dans T2 l'enregistrement correspondant à t2.cle avec lequel on a fait les updates précédents dans T1.

    Ma question : quelle est la requête ou les requêtes SQL pour effectuer cette tâche?

    Merci infiniment

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Bonjour,

    Il va vous falloir passer par une jointure entre les deux tables dans l'UPDATE, et utiliser l'instruction CASE.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> '555' AND t1.c1 = '555' THEN t2.c1
    		WHEN t2.c1 <> '555' AND t1.c1 <> '555' AND t2.c1 < t1.c1 THEN t2.c1
    	END
    , t2.c2 = 
    	CASE
    		WHEN t2.c2 <> '555' AND t1.c2 = '555' THEN t2.c2
    		WHEN t2.c2 <> '555' AND t1.c2 <> '555' AND t2.c2 < t1.c2 THEN t2.c2
    	END
    , t2.c3 = 
    	CASE
    		WHEN t2.c3 <> '555' AND t1.c3 = '555' THEN t2.c3
    		WHEN t2.c3 <> '555' AND t1.c3 <> '555' AND t2.c3 < t1.c3 THEN t2.c3
    	END
    C'est à tester, bien évidemment, dans une transaction pour éviter toute mise à jour erronée due à une éventuelle erreur dans la requête.
    Au passage, attention avec les ' : c1, c2 et c3 sont-elles des colonnes avec des entiers (auquel cas in ne faut pas mettre d'apostrophes dans la requête) ou avec des chaînes de caractères (auquel cas attention avec le < qui va vous amener des comportements que vous ne souhaiterez peut-être pas, comme par exemple '10' < '9' qui est vrai pour les chaînes de caractères).

  3. #3
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Pour la suppression des lignes de t2 qui ont servi à faire la mise à jour, alors la requête suivante devrait faire l'affaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DELETE t1
    FROM t1
    INNER JOIN t2 ON t1.cle = t2.cle
    WHERE (t2.c1 <> '555' AND t1.c1 = t2.c1) OR (t2.c2 <> '555' AND t1.c2 = t2.c2) OR (t2.c3 <> '555' AND t1.c3 = t2.c3)
    Encore une fois, à tester au préalable dans une transaction et faire ROLLBACK si ça se passe mal...

  4. #4
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Merci infiniment ced,
    Je teste la solution et je fais le retour, les champs c1 c2 et c3 sont des champs de type float et tous les champs sont inférieurs à 1 sauf ceux ayant la valeur par défaut 555. la virgule est remplacé par un point.
    Voici un exemple
    .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    0.123924 	0.158 	0.15 		
    0.123924 	0.158 	555 	
    0.11807 	555 	0.146 	
    0.133436 	555 	0.1554
    0.0202 	0.0046 	0.0285
    Merci d'avance

  5. #5
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    OK. Donc il faut bien enlever les apostrophes dans l'UPDATE, inutile de faire du transtypage pour rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> 555 AND t1.c1 = 555 THEN t2.c1
    		WHEN t2.c1 <> 555 AND t1.c1 <> 555 AND t2.c1 < t1.c1 THEN t2.c1
    	END
    , t2.c2 = 
    	CASE
    		WHEN t2.c2 <> 555 AND t1.c2 = 555 THEN t2.c2
    		WHEN t2.c2 <> 555 AND t1.c2 <> 555 AND t2.c2 < t1.c2 THEN t2.c2
    	END
    , t2.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3
    	END

  6. #6
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour seb,

    ça marche mais j'ai deux questions:

    Est ce que je peux utiliser une transaction (start transaction...fin) si mes tables sont par défaut MyIsam?

    J'ai un problème avec l'Update qui doit être certainement lié à ce dont vous m'avez mis en garde
    si dans t1 j'ai les champs c1,c2 et c3 comme suit
    et dans t2
    Pour une même clé
    alors au lieu de m'afficher
    ça m'affiche
    et partout où il y a des updates ça fait tout simplement

    Merci

  7. #7
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Bonjour,

    Avec MyIsam, pas de transactions possibles. Attention alors, à tester sur une base de tests.
    Sinon, quel est le type de chaque colonne ? Et quelle requête avez-vous finalement jouée ?

  8. #8
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour,
    la requête que j'utilise est la même que vous m'aviez envoyée. c'est à dire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> 555 AND t1.c1 = 555 THEN t2.c1
    		WHEN t2.c1 <> 555 AND t1.c1 <> 555 AND t2.c1 < t1.c1 THEN t2.c1
    	END
    , t2.c2 = 
    	CASE
    		WHEN t2.c2 <> 555 AND t1.c2 = 555 THEN t2.c2
    		WHEN t2.c2 <> 555 AND t1.c2 <> 555 AND t2.c2 < t1.c2 THEN t2.c2
    	END
    , t2.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3
    	END
    Toutefois, j'ai du dans mes tables t1 et T2 changer la clé primaire (car je veux pouvoir la dupliquer à l'intérieur d'une requête future (pas celle-là!)), j'en ai donc crée une nouvelle en autoincrement.

    Je voudrais par ailleurs savoir si dans la présente requête je peu changer d'autres champs à chaque fois que c1 ,c2 ou c3 est changé pour avoir des stat sur les changement effectués etc, car je vois pas comment je peux le faire avec les case. J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    t2.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3,nbchg=nbchg+1,
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3, nbchg=nbchg+1
    et ça me sort une erreur à tous les coups.

    Merci d'avance

  9. #9
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Ah non, ça ne marche pas comme ça...
    Il faut refaire une série de condition pour mettre le compteur à jour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> 555 AND t1.c1 = 555 THEN t2.c1
    		WHEN t2.c1 <> 555 AND t1.c1 <> 555 AND t2.c1 < t1.c1 THEN t2.c1
    	END
    , t2.c2 = 
    	CASE
    		WHEN t2.c2 <> 555 AND t1.c2 = 555 THEN t2.c2
    		WHEN t2.c2 <> 555 AND t1.c2 <> 555 AND t2.c2 < t1.c2 THEN t2.c2
    	END
    , t2.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3
    	END
    , nbchg = 
    	CASE ... END

  10. #10
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour,
    Merci infiniment de cette réponse ced. Je m'en suis bien douté. Pourtant cette variable nbchg (ou nombre de changements), j'en ai besoin pour connaître le nombre de nouvelles écritures, c'est pourquoi je veux la lier à chaque set des c1,c2 et C3, c'est pourquoi elle doit donc être incrémentée à chaque fois(histoire d'avoir un contrôle sur tout ce qui a bougé). Est ce possible d'y arriver avec seulement Mysql?

    Par ailleurs, j'ai oublié lors de mon précédent post que le problème de CAST, je suis bien empêtré dedans ;il me sort des valeurs 0 qui ne sont même pas dans mes données!! Est ce parce que je me sers du point comme virgule à l'anglaise dans phpmyadmin(en français )? Dois-je faire une manipulation supplémentaire dans l'outil graphique phpmyadmin pour qu'il accepte les points, ou bien remplacer tous les point par de vrais virgules avant import dans mysql?


    Enfin autre chose curieuse, la requête précédente qui n'est même pas censée toucher à la table T2, Eh bien après exécution de la requête me transforme des données dans T2 en 0!!!!

    Merci d'avance
    PS: normalement mes questions traitent de sujets divers, donc j'aurais du ouvrir une discussion pour chaque. Mais comme je rencontre tout au même moment...

  11. #11
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Euh, si les valeurs de t2 changent, c'est un peu de ma faute. Je me suis trompé dans l'UPDATE en mettant t2 au lieu de t1 sur la mise à jour des colonnes c2 et c3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> 555 AND t1.c1 = 555 THEN t2.c1
    		WHEN t2.c1 <> 555 AND t1.c1 <> 555 AND t2.c1 < t1.c1 THEN t2.c1
    	END
    , t1.c2 = 
    	CASE
    		WHEN t2.c2 <> 555 AND t1.c2 = 555 THEN t2.c2
    		WHEN t2.c2 <> 555 AND t1.c2 <> 555 AND t2.c2 < t1.c2 THEN t2.c2
    	END
    , t1.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3
    	END
    Pour compter le nombre de changements, il faut éventuellement passer par un trigger...

  12. #12
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    bonjour,
    Effectivement et bravo d'avoir vu ça. En tout cas j'ai rien vu moi.

    Merci infiniment.

    Pour ce qui est des triggers, on verra bien plus tard.

  13. #13
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    ?

  14. #14
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour,
    PRESQUE!
    Presque si ce n'est que si je change c2(il le change très correctement) alors il me met c1 à 0
    et s'il me change c1 correctement il met les autres ( c2 et c3) à 0. et je comprends pplus

    Merci beaucoup en tous cas

  15. #15
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Peut-être parce qu'il manque des ELSE dans les CASE. Comme je n'ai pas testé, on y va à tâtons... :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    UPDATE t1
    	INNER JOIN t2 ON t1.cle = t2.cle
    SET t1.c1 =
    	CASE
    		WHEN t2.c1 <> 555 AND t1.c1 = 555 THEN t2.c1
    		WHEN t2.c1 <> 555 AND t1.c1 <> 555 AND t2.c1 < t1.c1 THEN t2.c1
    		ELSE t1.c1
    	END
    , t1.c2 = 
    	CASE
    		WHEN t2.c2 <> 555 AND t1.c2 = 555 THEN t2.c2
    		WHEN t2.c2 <> 555 AND t1.c2 <> 555 AND t2.c2 < t1.c2 THEN t2.c2
    		ELSE t1.c2
    	END
    , t1.c3 = 
    	CASE
    		WHEN t2.c3 <> 555 AND t1.c3 = 555 THEN t2.c3
    		WHEN t2.c3 <> 555 AND t1.c3 <> 555 AND t2.c3 < t1.c3 THEN t2.c3
    		ELSE t1.c3
    	END

  16. #16
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour ced,
    Vous êtes génial. c'était bien ça qui manquait . Je l'ai testée et ça marche.

    Merci infiniment.

    Je marque donc en résolu!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Liaison conditionnelle entre 2 tables
    Par tomaa dans le forum Requêtes
    Réponses: 3
    Dernier message: 14/04/2011, 09h12
  2. UPDATE ID entre deux tables
    Par sarabaïte dans le forum Requêtes
    Réponses: 1
    Dernier message: 27/03/2011, 18h41
  3. update mutiple entre deux tables
    Par essayeencore dans le forum Développement
    Réponses: 2
    Dernier message: 05/07/2010, 16h01
  4. [AC-2007] Calcul conditionnel entre deux tables
    Par Wanaka dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 27/04/2009, 10h51
  5. update jointure entre 2 tables
    Par papy_tergnier dans le forum SQL
    Réponses: 2
    Dernier message: 16/10/2007, 17h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo