Précédent   Forum du club des développeurs et IT Pro > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 27/12/2012, 07h43   #1
LeHibou2
Membre du Club
 
Inscription : mai 2010
Messages : 164
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 164
Points : 41
Points : 41
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
LeHibou2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 09h20   #2
LeHibou2
Membre du Club
 
Inscription : mai 2010
Messages : 164
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 164
Points : 41
Points : 41
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 ?
LeHibou2 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 27/12/2012, 11h13   #3
Fred_34
Membre expérimenté
 
Homme Frédéric
Inscription : 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 : 576
Points : 576
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
Fred_34 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 27/12/2012, 11h54   #4
ok.Idriss
Responsable Modération

 
Avatar de ok.Idriss
 
Homme Idriss Neumann
Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)
Inscription : février 2009
Messages : 3 795
Détails du profil
Informations personnelles :
Nom : Homme Idriss Neumann
Âge : 22
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)

Informations forums :
Inscription : février 2009
Messages : 3 795
Points : 12 154
Points : 12 154
Bonjour.

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

Citation:
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

Citation:
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
ok.Idriss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 14h05   #5
LeHibou2
Membre du Club
 
Inscription : mai 2010
Messages : 164
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 164
Points : 41
Points : 41
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
LeHibou2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 14h33   #6
ok.Idriss
Responsable Modération

 
Avatar de ok.Idriss
 
Homme Idriss Neumann
Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)
Inscription : février 2009
Messages : 3 795
Détails du profil
Informations personnelles :
Nom : Homme Idriss Neumann
Âge : 22
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)

Informations forums :
Inscription : février 2009
Messages : 3 795
Points : 12 154
Points : 12 154
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

Citation:
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.

Citation:
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

Citation:
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.

Citation:
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

Citation:
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
ok.Idriss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 16h45   #7
LeHibou2
Membre du Club
 
Inscription : mai 2010
Messages : 164
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 164
Points : 41
Points : 41


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
LeHibou2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 16h52   #8
ok.Idriss
Responsable Modération

 
Avatar de ok.Idriss
 
Homme Idriss Neumann
Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)
Inscription : février 2009
Messages : 3 795
Détails du profil
Informations personnelles :
Nom : Homme Idriss Neumann
Âge : 22
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Consultant en SSII et auditeur au CNAM Paris (ingénieur SI)

Informations forums :
Inscription : février 2009
Messages : 3 795
Points : 12 154
Points : 12 154
Ok je suis rassuré
ok.Idriss est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 04h13.


 
 
 
 
Partenaires

Hébergement Web