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 :

Une jointure sûrement simple


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Points : 79
    Points
    79
    Par défaut Une jointure sûrement simple
    Bonjour à tous,

    Pour l'exemple, on va prendre une situation totalement virtuelle, mais qui représente simplement mon problème :


    Soit 3 tables : mere, garcon, fille, toutes telles que :
    Les tables garcon et fille sont reliées à mere par leur id.

    Maintenant, ma complication : il y a une quatrième table, appelé fruit, de structure identique aux autres, connectée à l'id fille par son id.

    Ce que je souhaite, c'est faire une jointure qui récupère aussi le nom du fruit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select * from mere
    join garcon on mere.id = garcon.id
    join fille on mere.id = garcon.id
     
    join fruit on fille.id = fruit.id
    J'ai espacé la jointure qui me pose problème. Je ne sais pas comment récupérer le nom du fruit dans la requête..

    Une piste ?

    Merci à vous,

    LeHibou

  2. #2
    Membre régulier
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Points : 79
    Points
    79
    Par défaut
    C'est bon, j'ai réglé mon problème avec des clauses where.

    Par contre, peut-on m'expliquer en quoi une jointure qui n'a rien à voir avec la table du from, nommée "mere" mais qui est reliée à une table elle-même reliée à "mere" ne me sort aucun résultat ?

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Ta seconde condition de jointure n'est pas bonne.

    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JOIN fille ON mere.id = garcon.id
    Il faut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JOIN fille ON mere.id = fille.id

  4. #4
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    +1 pour l'erreur dans la condition relevée par Fred_34.

    C'est bon, j'ai réglé mon problème avec des clauses where.
    Donc en gros tu fait la jointure dans le WHERE ce qui est dépréciée depuis 1992 => solution à proscrire

    Par contre, peut-on m'expliquer en quoi une jointure qui n'a rien à voir avec la table du from, nommée "mere" mais qui est reliée à une table elle-même reliée à "mere" ne me sort aucun résultat ?
    Le "*" (bien souvent à éviter surtout dans les requête avec jointure) ne se fait pas sur l'ensemble des tables du FROM mais sur la première (donc "mere").

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT mere.*, fruit.* FROM mere
    JOIN garcon ON mere.id = garcon.id
    JOIN fille ON mere.id = fille.id
    JOIN fruit ON fille.id = fruit.id
    Là tu aura également l'ensemble des colonnes de "fruit" dans le résultat de ta requête, mais il reste hautement préférable de bien définir les colonnes dont tu as besoin dans ton résultat. Certains te parleront d'éviter la "guerre des étoiles" qui nuit grandement à la lisibilité des requêtes d'une part et qui surtout alourdissent potentiellement le coût de la requête en nombre d'entrées/sorties. Par exemple ça peux induire de faire faire à l'optimiseur plus d'entrées/sorties parce que dans certains cas tu ne profite plus des indexes ce genre de choses.

    Même dans le cas où il te faut faire une sélection la totalité des colonnes, en indiquant précisément les colonnes que tu souhaites obtenir dans ton résultat, tu as au moins la maîtrise de ce que tu fait (et non pas une part de hasard) et si un jour tu rajoute pour X raison une colonne dans ta table, au moins elle n’alourdira pas la requête si tu ne l'utilise pas. De même si pour X raison, tu retire une colonne et qu'elle était nécéssaire à cette requête, tu te rendra compte de l'erreur beaucoup plus rapidement que si tu avait mis un "*".

    A vrai dire, le seul cas ou le "*" peux se justifier pour moi => c'est dans un count (là ça n'impacte pas les performances en terme de coût de la requête et le schéma de la table ne changera rien au résultat contrairement à une sélection de données).

    Cordialement,
    Idriss

  5. #5
    Membre régulier
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Points : 79
    Points
    79
    Par défaut
    Bonjour,

    L'erreur relevée par fred_34 est bien sûr une typo lorsque j'ai écrit, dans la vraie situation, elle n'était pas présente

    Pour le where, il est inclus dans une requête du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Select
    From
    Join.. on
    where
    Enfin, pour l'étoile, dans la solution finale , je ne sélectionne que 3 champs, précédés du nom diminutif de la table.

    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT mere.*, fruit.* FROM mere
    JOIN garcon ON mere.id = garcon.id
    JOIN fille ON mere.id = fille.id
    JOIN fruit ON fille.id = fruit.id
    fruit a fait que mysql a retourné 0 résultats alors qu'il y a correspondance de valeurs...

    Etrange, et c'était là mon étonnement !
    [edit] Réglé, je m'étais effectivement trompé de champ, mais pas comme dans mon exemple. Bref erreur d'étourderie..

    Mea culpa d'avoir pris de votre temps !

    A bientôt,

    LeHibou

  6. #6
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    Moi quand je vois ta requête, je me pose des questions sur la conception parce que sémantiquement parlant, ça veut dire qu'un identifiant se retrouve à la fois dans mere, fille, garçon et fruit

    Faudra nous expliquer ce que sa signifie mais logiquement

    mere.id == identifiant d'une occurrence de mere
    fille.id == identifiant d'une occurrence de fille
    Une fille peut être une mère, à la limite OK.

    garçon.id == identifiant d'une occurrence de garçon
    Une fille peut être une mère et un garçon en même temps, très original

    fruit.id == identifiant d'une occurrence de fruit
    Une fille peut être une mère et un garçon et un fruit en même temps

    Bon bref, pour moi cette requête ne veux absolument rien dire et tu as un gros problème de conception

    Voici une conception plus raisonnable

    Code autre : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Personne(id, name)
    Fille hérite de Personne
    Garçon hérite de Personne
    Contrainte de partition entre Fille et Garçon
    Fille -0,n- (être mère de) -0,1- Personne

    En gros au niveau relationnel tu aurais ça (une solution possible) :

    Code autre : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Fille(id, name, idMere#) avec idMere référence Fille.id
    Garçon(id, name, idMere#) avec idMere référence Fille.id

    Les fruits je vois pas trop ce qu'ils viennent faire dans ton histoire, faudra me donner davantage d'explication.

    Un peu de lecture (voir en particulier la partie héritage qui pourrait t'intéresser) : Initiation à la conception de bases de données relationnelles.

    Pour le where, il est inclus dans une requête du type
    Et dans ton WHERE, il y a quoi ? C'est pas parce que tu as fait une des jointures avec JOIN que ça te donne le droit de faire les autres via la clause WHERE

    Enfin, pour l'étoile, dans la solution finale , je ne sélectionne que 3 champs, précédés du nom diminutif de la table.
    Donc plus d'étoile dans ta requête ? Je reste catégorique à ce sujet, quelque soit le nombre de colonne sélectionnées (d'ailleurs plus tu sélectionne de colonnes, plus le "*" pourrait à la limite être compréhensible).

    Cordialement,
    Idriss

  7. #7
    Membre régulier
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Points : 79
    Points
    79
    Par défaut


    J'ai mis des noms à la con, il n'y a aucune logique dans l'exemple que j'ai donné.

    Non, il n'y a plus d'étoile non plus

    Et il n'y a pas de problème de conception, tout s'emboîte parfaitement dans un ensemble solide.

    Juste que je ne veux pas mettre des tables de 3 km de long et je renomme en fonction de ce qui me vient en tête au moment d'écrire.

    Je crois que j'avais notifié que l'exemple en soi n'était pas appliqué (totalement virtuel)

    Ce qui m'intéressait, c'était la logique.

    Merci beaucoup en tout cas

  8. #8
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Ok je suis rassuré

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

Discussions similaires

  1. [9.1] nested loop sur une jointure simple
    Par djaih dans le forum Requêtes
    Réponses: 8
    Dernier message: 13/02/2013, 17h24
  2. [MySQL] Erreur myql pour une jointure simple
    Par Alexandrebox dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 03/05/2010, 21h29
  3. [CR9] faire une Jointure externe
    Par coldec dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 28/06/2005, 13h10
  4. Comment optimiser une jointure ?
    Par seb_asm dans le forum Administration
    Réponses: 21
    Dernier message: 25/06/2004, 17h42
  5. Lignes en double dans le résultat d'une jointure
    Par ledevelopeur dans le forum Bases de données
    Réponses: 4
    Dernier message: 02/06/2004, 19h10

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