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 :

requete sur deux tables avec join et coalesce


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut requete sur deux tables avec join et coalesce
    Bonjour,

    Je suis novice dans le domaine (il vaut mieux preciser !)

    La requete qui me pose probleme concerne deux tables distinctes: original et revised
    Dans la premiere des donnees d'une manip scientifique (des moniteurs a neutrons) arrivent en temps reel
    et dans la deuxieme on place les eventuelles correction qui ont ete apportee a posteriori
    Chaque enregistrement a un timestamp unique. Exemple:

    timestamp-------------original
    2009-01-29 02:30:00-----780
    2009-01-29 02:31:00-----799
    2009-01-29 02:32:00-----783
    2009-01-29 02:33:00-----632
    2009-01-29 02:34:00-----null
    timestamp------------revised
    2009-01-29 02:31:00-----785
    2009-01-29 02:33:00-----null
    Je cherche une requete qui me permette de recuperer les valeurs originales, en les remplacant
    par les revisees si un timestamp correspond dans la table revised, et que les "null" soient bien pris en compte
    La requete doit donc me renvoyer:

    2009-01-29 02:30:00---780
    2009-01-29 02:31:00---785
    2009-01-29 02:32:00---783
    2009-01-29 02:33:00---null
    2009-01-29 02:34:00---null
    J'ai essayer ce type de requete:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT original.timestamp, COALESCE(revised, original) AS revoriginal
    FROM `original`
    LEFT JOIN `revised` ON original.timestamp = revised.timestamp
    WHERE original.timestamp > '2009-01-29 02:30:00'
    Ce qui marche sauf pour les valeurs "null" de revised... car COALESCE cherche la premiere valeur non "null" de la table
    Je precise qu'il n'est pas possible de remplacer ces valeurs null par des 0.

    Voila j'espere avoir ete clair !?

    Merci d'avance a tous ceux qui voudront bien se pencher sur le probleme.

  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 ,

    Citation Envoyé par nifufu Voir le message
    Ce qui marche sauf pour les valeurs "null" de revised... car COALESCE cherche la premiere valeur non "null" de la table
    Qu'entends-tu par les valeurs "null" de revised ? Le champ est à NULL ou alors il y a écrit "null" (chaîne de caractères) dans le champ ?
    Parce que si le champ est à NULL, COALESCE renvoie normalement original et si original vaut aussi NULL, alors COALESCE renvoie NULL...
    Ou alors, il faut préciser un peu le problème.

    ced

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Le champ est NULL (pas des caractères)
    Pour etre plus clair: je voudrais que si un timestamp de revised
    correspond a un timestamp de original, alors que ca soit la valeur
    de revised qui soit renvoyee, meme si celle-ci est NULL (qui n'est pas vraiment
    une valeur mais bon, c'est pour clarifier la situation)
    Nifu

  4. #4
    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 : 61
    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 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Il faut chercher le NULL de non correspondance dans la date et non pas dans revised :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT o.timestamp, CASE
      WHEN r.timestamp IS NULL THEN o.original
      ELSE r.revised
    END
    FROM original o
    LEFT JOIN revised r ON o.timestamp = r.timestamp
    WHERE o.timestamp > '2009-01-29 02:30:00'

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    J'essaye ca de suite et vous tiens au courant.
    Merci
    Nifufu

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Non en fait je ne vois pas comment cela pourrait marche ainsi
    vu que le timestamp n'est jamais NULL ?
    j'ecrirais plutot
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT o.timestamp, CASE
      WHEN r.timestamp IS NOT NULL THEN r.revised
      ELSE o.original
    END
    FROM original o
    LEFT JOIN revised r ON o.timestamp = r.timestamp
    WHERE o.timestamp > '2009-01-29 02:30:00'
    Mais ceci dit ca ne fonctionne pas mieux

  7. #7
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    comme ceci peut être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT o.timestamp, CASE
      WHEN r.revised IS NULL THEN o.original
      ELSE r.revised
    END
    FROM original o
    LEFT JOIN revised r ON o.timestamp = r.timestamp
    WHERE o.timestamp > '2009-01-29 02:30:00'

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    L'idee c'est justement de recuperer revised meme si cette valeur est NULL

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHEN r.revised IS NULL THEN o.original
      ELSE r.revised

  9. #9
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    peux tu nous donner les ordres de create et d'insert?

    Merci

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Voici un exemple d'INSERT pour les deux tables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    INSERT INTO `nmdb`.`STATION_ori` (
    `start_date_time` ,
    `length_time_interval_s` ,
    `measured_uncorrected` ,
    `measured_corr_for_efficiency` ,
    `measured_corr_for_pressure`
    )
    VALUES (
    '2008-07-09 19:53:40', '60', '600', '500', '400'
    )
    STATION_rev

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO `nmdb`.`STATION_rev` (
    `start_date_time` ,
    `length_time_interval_s` ,
    `revised_uncorrected` ,
    `revised_corr_for_efficiency` ,
    `revised_corr_for_pressure` ,
    `version` ,
    `last_change`
    )
    VALUES (
    '2008-07-09 19:55:36', '60', '650', '500', '550', '1',
    CURRENT_TIMESTAMP
    )

  11. #11
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    mais si on n'a pas les create et tous les insert, difficile de tester...

    et n'oublie pas les balises codes !!

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Heu la ca depasse un peu mes competences...
    Je n'ai pas creer les tables moi meme, j'essaye juste
    de les utiliser pour une interface web php/mysql
    L'exemple que j'ai donne au debut ne suffit pas pour se faire une idee
    du pb ? je peux en donner un autre si besoin est.
    cdtl
    Nifu

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Et ca sera pour plus tard, WE oblige!
    Bon WE aux developpeurs

  14. #14
    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 : 61
    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 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par nifufu Voir le message
    Non en fait je ne vois pas comment cela pourrait marche ainsi
    vu que le timestamp n'est jamais NULL ?
    Aurais-je mal compris ?
    La table revised ne contient pas que les lignes révisées mais toutes les lignes présentes dans la table original ?

    Dans la requête que je proposais, et que je redonne ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT o.timestamp, CASE
      WHEN r.timestamp IS NULL THEN o.original
      ELSE r.revised
    END
    FROM original o
    LEFT JOIN revised r ON o.timestamp = r.timestamp
    WHERE o.timestamp > '2009-01-29 02:30:00'
    On fait une jointure externe gauche entre original et revised. Cette requête doit donc logiquement donner toutes les lignes de original et la correspondance quand elle existe de revised. S'il n'y a pas de correspondance, les colonnes de la table revised ont la valeur NULL. Donc revised.timestamp devrait avoir la valeur NULL et c'est justement ce qui est testé dans le CASE WHEN.

    Je teste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE  TABLE  `test`.`STATION_ori` ( `start_date_time` DATETIME NOT  NULL ,
     `length_time_interval_s` INT  ,
     `measured_uncorrected` INT ,
     `measured_corr_for_efficiency` INT  ,
     `measured_corr_for_pressure` INT 
    ) ENGINE  =  MYISAM
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE  TABLE  `test`.`STATION_rev` ( `start_date_time` DATETIME NOT  NULL ,
     `length_time_interval_s` INT,
     `revised_uncorrected` INT ,
     `revised_corr_for_efficiency` INT  ,
     `revised_corr_for_pressure` INT ,
     `version` INT ,
     `last_change` INT
    ) ENGINE  =  MYISAM
    J'ai inséré 4 lignes dans STATION_ori (je ne donne que les deux colonnes qui nous intéressent dans la requête plus bas) :
    start_date_time measured_corr_for_efficiency
    2008-07-09 19:53:40 500
    2008-07-09 19:54:50 400
    2008-07-09 19:55:00 500
    2008-07-09 19:55:30 500
    et deux dans STATION_rev :
    start_date_time revised_corr_for_efficiency
    2008-07-09 19:55:00 200
    2008-07-09 19:54:50 NULL
    Dans STATION_rev, J'ai modifié une mesure sur une ligne et j'ai mis à NULL la même colonne sur la deuxième ligne (voir en gras ci-dessus)

    Voilà la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT o.start_date_time, CASE
      WHEN r.start_date_time IS NULL THEN o.measured_corr_for_efficiency
      ELSE r.revised_corr_for_efficiency
    END AS Final
    FROM STATION_ori o
    LEFT JOIN STATION_rev r ON o.start_date_time = r.start_date_time
    Et voilà le résultat :
    start_date_time Final
    2008-07-09 19:53:40 500
    2008-07-09 19:54:50 NULL
    2008-07-09 19:55:00 200
    2008-07-09 19:55:30 500

  15. #15
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Genial CinePhil ca fonctionne parfaitement !

    Lors du test de ta solution j'avais des erreurs
    de frappe... mea culpa. Après vérification j'obtiens
    bien des champs NULL lorsque les revised sont NULL.

    merci

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

Discussions similaires

  1. Requete sur deux tables avec tri
    Par ebaoo dans le forum MySQL
    Réponses: 2
    Dernier message: 25/02/2010, 18h41
  2. [AC-2003] Requete sur une table avec des "Left Join" en parallèle
    Par Currahee dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 27/08/2009, 09h37
  3. Réponses: 10
    Dernier message: 11/08/2009, 14h43
  4. Requetes sur deux tables avec plusieurs retour
    Par IP-Fix dans le forum Requêtes
    Réponses: 16
    Dernier message: 13/11/2008, 18h46
  5. Requete sur deux tables
    Par ReaseT dans le forum ASP
    Réponses: 13
    Dernier message: 07/02/2005, 16h18

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