Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Membre du Club
    Inscrit en
    mai 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : mai 2010
    Messages : 178
    Points : 51
    Points
    51

    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 :
    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 du Club
    Inscrit en
    mai 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : mai 2010
    Messages : 178
    Points : 51
    Points
    51

    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 chevronné
    Homme Profil pro Frédéric
    Inscrit en
    juin 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Nom : Homme Frédéric
    Localisation : France

    Informations forums :
    Inscription : juin 2011
    Messages : 442
    Points : 612
    Points
    612

    Par défaut

    Ta seconde condition de jointure n'est pas bonne.

    Au lieu de :
    Code :
    JOIN fille ON mere.id = garcon.id
    Il faut :
    Code :
    JOIN fille ON mere.id = fille.id

  4. #4
    Responsable Modération

    Avatar de ok.Idriss
    Homme Profil pro Idriss Neumann
    Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Inscrit en
    février 2009
    Messages
    5 040
    Détails du profil
    Informations personnelles :
    Nom : Homme Idriss Neumann
    Âge : 24
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2009
    Messages : 5 040
    Points : 17 545
    Points
    17 545

    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 :
    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
    mes cours sur DVP | initiation aux bases de données relationnelles | FAQ Linux | FAQ tests
    la programmation Shell | bonnes pratiques Bash | exercices shells scripts & Bash corrigés
    Merci aussi de lire les règles du club

    "Forgiveness does not change the past, but it does enlarge the future." (Paul Boese)
    Traduction approximative : le pardon ne change pas le passé mais élargit l'horizon de l'avenir.

  5. #5
    Membre du Club
    Inscrit en
    mai 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : mai 2010
    Messages : 178
    Points : 51
    Points
    51

    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 :
    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 :
    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
    Responsable Modération

    Avatar de ok.Idriss
    Homme Profil pro Idriss Neumann
    Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Inscrit en
    février 2009
    Messages
    5 040
    Détails du profil
    Informations personnelles :
    Nom : Homme Idriss Neumann
    Âge : 24
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2009
    Messages : 5 040
    Points : 17 545
    Points
    17 545

    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 :
    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 :
    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
    mes cours sur DVP | initiation aux bases de données relationnelles | FAQ Linux | FAQ tests
    la programmation Shell | bonnes pratiques Bash | exercices shells scripts & Bash corrigés
    Merci aussi de lire les règles du club

    "Forgiveness does not change the past, but it does enlarge the future." (Paul Boese)
    Traduction approximative : le pardon ne change pas le passé mais élargit l'horizon de l'avenir.

  7. #7
    Membre du Club
    Inscrit en
    mai 2010
    Messages
    178
    Détails du profil
    Informations forums :
    Inscription : mai 2010
    Messages : 178
    Points : 51
    Points
    51

    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
    Responsable Modération

    Avatar de ok.Idriss
    Homme Profil pro Idriss Neumann
    Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Inscrit en
    février 2009
    Messages
    5 040
    Détails du profil
    Informations personnelles :
    Nom : Homme Idriss Neumann
    Âge : 24
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant en SSII et ingénieur CNAM Paris (spécialité SI)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2009
    Messages : 5 040
    Points : 17 545
    Points
    17 545

    Par défaut

    Ok je suis rassuré
    mes cours sur DVP | initiation aux bases de données relationnelles | FAQ Linux | FAQ tests
    la programmation Shell | bonnes pratiques Bash | exercices shells scripts & Bash corrigés
    Merci aussi de lire les règles du club

    "Forgiveness does not change the past, but it does enlarge the future." (Paul Boese)
    Traduction approximative : le pardon ne change pas le passé mais élargit l'horizon de l'avenir.

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •