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

Langage SQL Discussion :

Mise à jour d'une table à partir du résultat d'une requête


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut Mise à jour d'une table à partir du résultat d'une requête
    Bonjour,

    je cherche à faire quelque chose qui me semble relativement simple mais apriori pas assez car je n'y arrive pas...

    Je vous explique, je cherche à UPDATE une table à partir d'un résultat d'une requête qui touche d'autre table (calcul de moyenne etc...). Je ne sais pas du tout comment m'y prendre et ne vois pas dans quel sens prendre le problème.

    Informations :

    SGBD : MySQL

    Structure de ma table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE IF NOT EXISTS `mjoba` (
      `Job_idJob` int(11) NOT NULL,
      `Quantite` int(2) default NULL,
      `NomJob` varchar(30) default NULL,
      `Date` year(4) default NULL,
      `Moyenne` time default NULL,
      KEY `MA_FKIndex1` (`Job_idJob`),
      KEY `Quantite` (`Quantite`),
      KEY `NomJob` (`NomJob`),
      KEY `Date` (`Date`),
      KEY `Moyenne` (`Moyenne`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    Ma requête (qui fonctionne et qui ne pose pas de problème)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT 
    			COUNT(Job_idJob),
    			Job.idJob,
    			Job.NomJob,
    			SUBSTR(Debut,1,4),
    			SEC_TO_TIME(Avg(TIME_TO_SEC(Temp)))
    FROM DureeJob 
    INNER JOIN Job ON DureeJob.Job_idJob=Job.idJob 
    AND job.nomjob LIKE '%-%A-%'
    GROUP BY 
    			SUBSTR(DEBUT,1,4),
    			job_idjob 
    ORDER BY `Job`.`NomJob` ASC
    Extrait du résultat :

    Job_idJob, Quantite, NomJob, Date, Moyenne
    6400, 1, PROCZ-100A-010D, 2009, 00:00:10
    6401, 3, PROCZ-100A-020D, 2009, 00:00:19
    6402, 21, PROCZ-100A-030D, 2009, 00:00:19
    6403, 5, PROCZ-100A-040D, 2009, 00:00:11
    Explications complémentaires :

    Ce que j'aimerais pouvoir faire ici, c'est d'insérer dans la table MJOBA le résultat de ma requête sauf que les arguments de UPDATE comme le SET m'induisent un peu en erreur... J'ai aussi pensé à insérer dans une table temporaire le résultat de la requête pour ensuite les insérer mais je n'ai rien pu faire de concluant...

    Aussi, j'ai un problème assez particulier, la requête sort un résultat bien groupé d'une certaine manière et séparer les arguments chamboulerais un peu tout (d'où ma difficulté à faire une "UPDATE TABLE SET CHAMP1=X, CHAMP2=Y"). La requête doit UPDATE la table et non pas l'INSERT.

    Si quelqu'un a une idée de génie ca serait formidable !
    Merci d'avance à tous !

  2. #2
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut
    Ah aussi petite précision, j'aimerais en gros transvaser le résultat de ma requête dans ma table MJOBA et ne pas mettre à jour les lignes déjà présentes si elle sont identiques à celles de la requête. J'espère que cela aidera à la compréhension de mon problème.

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Bonjour et merci d'avoir respecté les règles du forum, ça fait plaisir et c'est clair.

    Il n'y a pas de clé primaire dans la table 'mjoba' mais me trompé-je en supposant que la colonne 'Job_idJob' est une clé candidate, c'est à dire qu'il n'y a pas deux 'Job_idJob' identiques dans la table ?

    ne pas mettre à jour les lignes déjà présentes si elle sont identiques à celles de la requête.
    Identiques sur toutes les colonnes ?

    Tu peux faire un UPDATE avec une jointure. Ca donnerait quelque chose du genre :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    UPDATE mjoba
    INNER JOIN (
      SELECT 
        COUNT(Job_idJob) AS Qte,
        Job.idJob,
        Job.NomJob,
        SUBSTR(Debut,1,4) AS Annee,
        SEC_TO_TIME(Avg(TIME_TO_SEC(Temp))) AS Moyenne
      FROM DureeJob 
      INNER JOIN Job ON DureeJob.Job_idJob = Job.idJob 
      WHERE job.nomjob LIKE '%-%A-%'
      GROUP BY 
        SUBSTR(DEBUT,1,4),
        job_idjob 
      ORDER BY Job.NomJob ASC
    ) AS tmp ON mjoba.Job_idJob = tmp.idJob
    SET 
      mjoba.Quantite = tmp.Qte,
      mjoba.NomJob = tmp.NomJob
      mjoba.Date = tmp.Annee
      mjoba.Moyenne = tmp.Moyenne
    WHERE 
      mjoba.Job_idJob = tmp.idJob AND (
        mjoba.Quantite <> tmp.Qte OR
        mjoba.NomJob <> tmp.NomJob OR
        mjoba.Date <> tmp.Annee OR
        mjoba.Moyenne <> tmp.Moyenne
      )
    A adapter selon ton besoin réel.

    Au passage, c'est une mauvaise idée d'avoir appelé une colonne 'Date' car c'est un mot réservé du SQL.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut
    Alors d'abord merci beaucoup pour ta réponse. Pour ce qui est des Job_idJob, ce n'est pas un UNIQUE.
    Enfaite dans cette table je fais la moyenne des JOBS annuels par année (un peu bebete mais certains jobs annuel peuvent être lancés plusieurs fois par an...)
    La seule chose pour laquelle je ne veux pas re-UPDATE des lignes identiques est la perte de temps CPU-elapsed.
    Si la totalité de la ligne (moyenne comprise) est identique, rien ne sert de l'update...
    Je vais tester le tout !

  5. #5
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    Reste a savoir si le traitement du test sera moins penalisant que l'update complet... a voir

    Bon courage
    Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)

  6. #6
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut
    J'ai une petite question sur la clause WHERE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    WHERE 
        mjoba.Job_idJob = tmp.idJob AND (
        mjoba.Quantite <> tmp.Qte OR
        mjoba.NomJob <> tmp.NomJob OR
        mjoba.Date <> tmp.Annee OR
        mjoba.Moyenne <> tmp.Moyenne
      )
    La traduction de celle-ci est-elle :
    On execute l'UPDATE dans les cas ou les IDs sont égaux ET (les quantités sont différentes OU les noms sont différents OU les années sont différentes OU les moyennes sont différentes)

    Ma question est, dans le cas d'une ligne de la table MJOBA inexistante, est-ce que la nouvelle ligne calculée dans la table temporaire sera inséré dans la table MJOBA ?

    Est-ce que les lignes de la table MJOBA comme ci dessous seront updatées par les nouvelles lignes de la table Tmp ? :

    Table MJOBA
    Job_idJob Quantite NomJob Date Moyenne
    6400 1 PROCZ-100A-010D 2009 00:00:10
    Par -->

    Table Tmp
    Job_idJob Quantite NomJob Date Moyenne
    6400 2 PROCZ-100A-010D 2009 00:00:12
    Dans le cas ou il y aurait de nouveaux IDJOBs j'aimerais qu'il les INSERT automatiquement car si j'ai bien compris dans le cas de cette requête il se contente que de la mise à jour des données existante dans la table MJOBA mais pas des nouvelles calculées dans la table TMP...

    Merci d'avance

  7. #7
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut
    J'ai pensé à un truc, je ne sais pas si c'est judicieux de faire ça et je ne sais même pas comment le faire mais si on met une condition NOT EXISTS INSERT est-ce que ça fonctionnerait et quelle tête ça aurait ??

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'ai une petite question sur la clause WHERE :

    Code :
    WHERE
    mjoba.Job_idJob = tmp.idJob AND (
    mjoba.Quantite <> tmp.Qte OR
    mjoba.NomJob <> tmp.NomJob OR
    mjoba.Date <> tmp.Annee OR
    mjoba.Moyenne <> tmp.Moyenne
    )
    La traduction de celle-ci est-elle :
    On execute l'UPDATE dans les cas ou les IDs sont égaux ET (les quantités sont différentes OU les noms sont différents OU les années sont différentes OU les moyennes sont différentes)
    Bonne traduction.
    Ma question est, dans le cas d'une ligne de la table MJOBA inexistante, est-ce que la nouvelle ligne calculée dans la table temporaire sera inséré dans la table MJOBA ?
    Non puisque c'est un UPDATE et pas un INSERT.

    Est-ce que les lignes de la table MJOBA comme ci dessous seront updatées par les nouvelles lignes de la table Tmp ? :

    Table MJOBA
    Citation:
    Job_idJob Quantite NomJob Date Moyenne
    6400 1 PROCZ-100A-010D 2009 00:00:10
    Par -->

    Table Tmp
    Citation:
    Job_idJob Quantite NomJob Date Moyenne
    6400 2 PROCZ-100A-010D 2009 00:00:12
    Oui puisque Quantité et Moyenne sont différents.

    Dans le cas ou il y aurait de nouveaux IDJOBs j'aimerais qu'il les INSERT automatiquement car si j'ai bien compris dans le cas de cette requête il se contente que de la mise à jour des données existante dans la table MJOBA mais pas des nouvelles calculées dans la table TMP...
    Exactement. Les nouveaux idJob ne seront pas insérés.

    J'ai pensé à un truc, je ne sais pas si c'est judicieux de faire ça et je ne sais même pas comment le faire mais si on met une condition NOT EXISTS INSERT est-ce que ça fonctionnerait et quelle tête ça aurait ??
    En cherchant rapidement dans la doc, je n'ai pas trouvé cette syntaxe pour un INSERT.
    Par contre, j'y ai trouvé REPLACE qui serait peut-être bien pour ton cas.
    A creuser.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 24
    Points : 13
    Points
    13
    Par défaut
    Si je TRUNCATE ma table et qu'ensuite je me cantonne simplement à réinsérer la totalité de mes données de la table tmp est-ce que ça serait plus rapide dans la mesure ou je ne ferais aucune vérification ou comparaison?

    Si c'est plus intéressant quelle serait la requête avec la syntaxe du INSERT.
    Ce que j'ai pu trouver sur le INSERT c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO Table (Champ1,champ2...) VALUES (...,...)
    Comment imbriquer ma requête de calcul de moyenne dans ça ?

    Pour le REPLACE la syntaxe est similaire à l'INSERT donc je ne sais pas non plus comment placer ma requête !

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Si je TRUNCATE ma table et qu'ensuite je me cantonne simplement à réinsérer la totalité de mes données de la table tmp est-ce que ça serait plus rapide dans la mesure ou je ne ferais aucune vérification ou comparaison?
    C'est bien possible en effet !

    Si c'est plus intéressant quelle serait la requête avec la syntaxe du INSERT.
    Tout simplement un INSERT SELECT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    INSERT INTO mjoba(Job_idJob, Quantite, NomJob, `Date`, Moyenne)
    SELECT 
      Job.idJob,
      COUNT(Job_idJob) AS Qte,
      Job.NomJob,
      SUBSTR(Debut,1,4) AS Annee,
      SEC_TO_TIME(Avg(TIME_TO_SEC(Temp))) AS Moyenne
    FROM DureeJob 
    INNER JOIN Job ON DureeJob.Job_idJob = Job.idJob 
    WHERE job.nomjob LIKE '%-%A-%'
    GROUP BY 
      SUBSTR(DEBUT,1,4),
      job_idjob 
    ORDER BY Job.NomJob ASC
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Membre éclairé Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Points : 769
    Points
    769
    Par défaut
    Bonjour,

    Je n'ai pas trouvé de syntaxe REPLACE dans la norme SQL:2003. Dans quelle doc l'avez_vous trouvé ?

    Arkhena
    A bove ante, ab asino retro, a stulto undique caveto

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Ce n'est peut-être pas normatif mais c'est dans MySQL qui est le SGBD de l'initiateur de cette discussion.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  13. #13
    Membre éclairé Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Points : 769
    Points
    769
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Ce n'est peut-être pas normatif mais c'est dans MySQL qui est le SGBD de l'initiateur de cette discussion.
    Ah OK. Merci. (C'était juste pour ma culture personnelle)
    A bove ante, ab asino retro, a stulto undique caveto

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

Discussions similaires

  1. UPDATE d'une table à partir des résultats d'une requête
    Par pascal_06 dans le forum Langage SQL
    Réponses: 8
    Dernier message: 05/12/2013, 15h08
  2. Alimenter une table à partir du résultat d'une requete
    Par flateur18 dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 05/04/2011, 10h24
  3. [AC-97] Création d'une table à partir des résultats d'une requete analyse croisée
    Par docjo dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 11/11/2009, 21h46
  4. Réponses: 7
    Dernier message: 16/01/2007, 15h54
  5. Réponses: 8
    Dernier message: 11/08/2006, 09h30

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