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 :

Deux jointures vers la même table ?


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Deux jointures vers la même table ?
    Bonjour à tous,

    Je suis tellement novice en (My)SQL que je me permets de poser une question qui paraîtra sûrement triviale à beaucoup d'entre vous.

    Alors voilà, j'ai une table « personnes » :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE `personnes` (
      `id` tinyint(3) unsigned NOT NULL,
      `nom` varchar(30) NOT NULL,
      PRIMARY KEY (`id`)
    )
     
    INSERT INTO `personnes` (`id`, `nom`) VALUES
    (1, 'Albert'),
    (2, 'Béatrice'),
    (3, 'Carole'),
    (4, 'Daniel'),
    (5, 'Emilie');
    Et j'ai une table « animaux » avec deux propriétaires par animal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE `animaux` (
      `id` tinyint(3) unsigned NOT NULL,
      `nom` varchar(30) NOT NULL,
      `proprietaire1` tinyint(3) unsigned NOT NULL,
      `proprietaire2` tinyint(3) unsigned NOT NULL,
      PRIMARY KEY (`id`)
    );
     
    INSERT INTO `animaux` (`id`, `nom`, `proprietaire1`, `proprietaire2`) VALUES
    (1, 'Médor', 2, 3),
    (2, 'Minou', 1, 5),
    (3, 'Dumbo', 2, 4);
    Comment faire, en une seule requête, pour récupérer les noms des deux propriétaires de chaque animal, avec un résultat de ce genre :

    1, Médor, Béatrice, Carole
    2, Minou, Albert, Emilie
    3, Dumbo, Béatrice, Daniel

    Je suis sûr que c'est très facile, mais je ne trouve pas...
    Toute aide est bienvenue ! Merci...

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 738
    Points
    11 738
    Par défaut
    Il faut utiliser deux fois la table Personnes avec deux alias différents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT A.id, A.nom, P1.nom, P2.nom
    FROM Animaux A
      INNER JOIN Personnes P1 ON A.proprietaire1 = P1.id
      INNER JOIN Personnes P2 ON A.proprietaire2 = P2.id

  3. #3
    Membre éclairé Avatar de nsanabi
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2003
    Messages : 570
    Points : 678
    Points
    678
    Par défaut
    ou bien avec un prédicat (si impossible d'utiliser la jointure naturel)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT A.id, A.nom, P1.nom, P2.nom
    FROM Animaux A,Personnes P1,Personnes P2
    WHERE A.proprietaire1 = P1.id AND A.proprietaire2 = P2.id
    mais la solution de Antoun reste la plus optimisée je pense

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 738
    Points
    11 738
    Par défaut
    Citation Envoyé par nsanabi Voir le message
    ou bien avec un prédicat (si impossible d'utiliser la jointure naturel)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT A.id, A.nom, P1.nom, P2.nom
    FROM Animaux A,Personnes P1,Personnes P2
    WHERE A.proprietaire1 = P1.id AND A.proprietaire2 = P2.id
    mais la solution de Antoun reste la plus optimisée je pense
    Techniquement c'est supposé être exactement la même chose, modulo le fait qu'effectivement MySQL optimise parfois mieux les JOIN que le WHERE.

    Mais surtout, moi je fais les jointures en écriture normalisée, et non à la cochon (ou à la Oracle 8, assez bien placé parmi les ongulés) dans le WHERE

  5. #5
    Membre éclairé Avatar de nsanabi
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2003
    Messages : 570
    Points : 678
    Points
    678
    Par défaut
    merci pour l'information

    mais justement si le sgbd (oracle8 entre autres) n'intègre pas le join la variante que j'ai proposé à ta solution fonctionnera correctement

  6. #6
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Merci !
    Merci pour vos réponses, c'est exactement ce que je cherchais !

  7. #7
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 738
    Points
    11 738
    Par défaut
    Citation Envoyé par nsanabi Voir le message
    merci pour l'information

    mais justement si le sgbd (oracle8 entre autres) n'intègre pas le join la variante que j'ai proposé à ta solution fonctionnera correctement
    MySQL intègre

  8. #8
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Encore une question
    Oups... j'ai encore une question !

    Supposons que j'ajoute une ligne à ma table "animaux" et qu'elle ressemble désormais à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO `animaux` (`id`, `nom`, `proprietaire1`, `proprietaire2`) VALUES
    (1, 'Médor', 2, 3),
    (2, 'Minou', 1, 5),
    (3, 'Dumbo', 2, 4),
    (4, 'Titi', 2, NULL);
    Les requêtes que vous m'avez aimablement indiquées ne renvoient pas, dans ce cas, la ligne 4.
    Que faudrait-il faire pour obtenir un résultat "complet" du type :

    1, Médor, Béatrice, Carole
    2, Minou, Albert, Emilie
    3, Dumbo, Béatrice, Daniel
    4, Titi, Béatrice, [NULL ou vide...]

    Merci encore pour votre aide.

  9. #9
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Réponse possible
    Je m'auto-réponds et propose ceci pour résoudre le problème (qui doit vous paraître bien simple ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT A.id, A.nom, P1.nom, P2.nom
    FROM animaux A
      LEFT OUTER JOIN personnes P1 ON A.proprietaire1 = P1.id
      LEFT OUTER JOIN personnes P2 ON A.proprietaire2 = P2.id
    N'y aurait-il pas mieux comme requête dans ce cas ?

  10. #10
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 738
    Points
    11 738
    Par défaut
    Non, s'il y a une amélioration à chercher, elle est du côté de la modélisation :
    Personnes (id, nom)
    Animaux(id, nom)
    Appartenances(id_proprio, id_animal)
    Du coup, tu peux avoir 0 à n propriétaires par animal. Tu peux ensuite utiliser un GROUP_CONCAT pour reconstituer la liste des propriétaires :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT A.id, A.nom, GROUP_CONCAT(P.nom ORDER BY P.nom SEPARATOR ', ') as Proprietaires
    FROM Animal A
      INNER JOIN Appartenances AP ON A.id = AP.id_animal
      INNER JOIN Personnes P ON A.id APP.id_proprio = P.id
    GROUP BY A.id, A.nom

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/07/2013, 15h02
  2. Deux jointures vers la même table
    Par albedo0 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 17/02/2012, 09h10
  3. [AC-2002] Deux formulaires qui pointent vers une même table
    Par antezi dans le forum IHM
    Réponses: 2
    Dernier message: 11/02/2010, 21h27
  4. [MySQL] Jointure: Avec deux champs d'une même table
    Par Vinuto dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 25/11/2008, 20h10
  5. Jointure entre deux champs d'une même table
    Par oubli dans le forum Requêtes
    Réponses: 8
    Dernier message: 11/12/2007, 16h20

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