De jointures à Sous-requêtes

Fermé
SHAPE_OF_DESPAIR Messages postés 7 Date d'inscription mercredi 8 février 2017 Statut Membre Dernière intervention 16 février 2017 - Modifié par jordane45 le 13/02/2017 à 13:54
SHAPE_OF_DESPAIR Messages postés 7 Date d'inscription mercredi 8 février 2017 Statut Membre Dernière intervention 16 février 2017 - 16 févr. 2017 à 13:28
Bonjour,
je suis le cours SQL d'OpenClassRoom.
J'aimerais passer une jointure en sous-requête et n'y parviens pas.
Voici la donnée :

"Vous devez obtenir la liste des races de chiens qui sont des chiens de berger.
On considère (même si ce n'est pas tout à fait vrai) que les chiens de berger ont "berger" dans leur nom de race."

La table principale est Animal (avec les données des animaux, id, nom, sexe, date_naissance, commentaires, pere_id, mere_id, race_id, espece_id), et les autres tables comme Race, Espece ...

Voici la réponse :
SELECT Race.nom AS Race
FROM Race
INNER JOIN Espece
ON Race.espece_id = Espece.id
WHERE Espece.nom_courant = 'chien'
AND Race.nom LIKE '%berger%';


Par contre, je n'arrive pas à la passer en sous-requête.
Auriez-vous la solution histoire que je me familiarise avec le cheminement ?
Merci d'avance.=

EDIT : Ajout des balises de code

1 réponse

Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
13 févr. 2017 à 11:47
Bonjour,

Je n'ai pas trop compris s'il fallait garder ou non un INNER JOIN.

Si oui, a priori, il s'agit d'intégrer la condition Espece.nom_courant = 'chien' au sein de la clause INNER JOIN. Pour cela il faut définir une sous-table sous la forme d'un simple SELECT qui renvoie les champs dont on a besoin.

Cela se code de la façon suivante :

SELECT Race.nom AS Race
FROM Race
INNER JOIN (SELECT id FROM Espece WHERE nom_courant = 'chien') e
ON Race.espece_id = e.id
WHERE Race.nom LIKE '%berger%';

On a donc un sous-ensemble de Espece, nommé e, qui contient juste la colonne id, et juste les lignes où nom_courant = 'chien'.

Une autre solution, si tu ne dois pas garder le INNER JOIN, est d'utiliser un champ IN, en gardant la même sous-requête :
SELECT nom AS Race
FROM Race
WHERE espece_id IN (SELECT id FROM Espece WHERE nom_courant = 'chien') AND nom LIKE '%berger%';


Dans les deux cas, le principe reste le même : identifier le sous-ensemble de la table Espèce qui contient les données nécessaires.

Xavier
0
SHAPE_OF_DESPAIR Messages postés 7 Date d'inscription mercredi 8 février 2017 Statut Membre Dernière intervention 16 février 2017
13 févr. 2017 à 16:11
Merci Xavier, les deux fonctionnent parfaitement.
L'idée de base était en effet de supprimer le INNER JOIN.
Dites, par "identifier le sous-ensemble", parlez-vous dans le cas présent de l'élément 'chien' dans nom_courant ? Est-ce exact ?
0
Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011 > SHAPE_OF_DESPAIR Messages postés 7 Date d'inscription mercredi 8 février 2017 Statut Membre Dernière intervention 16 février 2017
14 févr. 2017 à 10:00
Oui, c'est bien ça.
On peut aussi retourner les requêtes, et sélectionner sur Espece avec jointure sur Race, auquel cas le sous-ensemble devient les Races ayant "berger" dans leur nom.
Cette souplesse ne fonctionne qu'avec un INNER JOIN, un des intérêts de cette clause qui peut paraître obscure de prime abord.
Ce qui donne :
SELECT r.nom AS Race
FROM Espece
INNER JOIN (SELECT espece_id, nom FROM Race WHERE nom LIKE '%berger%') r
ON Espece.id = r.espece_id
WHERE nom_courant = 'chien';
0
SHAPE_OF_DESPAIR Messages postés 7 Date d'inscription mercredi 8 février 2017 Statut Membre Dernière intervention 16 février 2017 > Reivax962 Messages postés 3672 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021
16 févr. 2017 à 13:28
Super, merci pour ces précisions.
0