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

Langage SQL Discussion :

jointure sur elle-même ?


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 25
    Points : 21
    Points
    21
    Par défaut jointure sur elle-même ?
    Bonjour

    J'ai une série de 3 tables :
    objet(*id_objet,...)
    lien(*id_objet,*id_personne)
    personne(*id_personne,nom,...)
    > voyez les clés étrangères tout ça...

    je voudrai les objets qui sont d'un auteur/personne et pas d'un autre.

    J'ai tenté la double jointure...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT objet.id AS id, T0.p_nom AS T0, T1.p_nom AS T1
    FROM objet 
    LEFT OUTER JOIN lien_op AS L0 ON objet.id_objet = L0.objets_id 
    LEFT OUTER JOIN personnes AS T0 ON L0.personnes_id = T0.id 
    LEFT OUTER JOIN lien_op AS L1 ON objet.id_objet = L1.objets_id 
    LEFT OUTER JOIN personnes AS T1 ON L0.personnes_id = T1.id
    WHERE 
    ( ( T0.p_nom LIKE '%tralala%' ) ) 
    AND 
    ( ( T1.p_nom NOT LIKE '%trululu%' ) )
    Mais ça donne pas ce que je veux

    Des pistes ?

    Nico

  2. #2
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Les objets qui sont liés à la personne A :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT o.id
    FROM objets o
    INNER JOIN liens LO ON o.id = LO.objets_id
      INNER JOIN personnes p ON LO.personne_id = p.id
    WHERE p.nom = 'A'

    Les objets qui ne sont pas liés à la personne B :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT o.id
    FROM objets o
    INNER JOIN liens LO ON o.id = LO.objets_id
      INNER JOIN personnes p ON LO.personne_id = p.id
    WHERE p.nom <> 'B'

    Une jointure pour trouver ceux qui sont dans les deux requêtes et le tour est joué :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT DISTINCT t1.id
    FROM (
      SELECT o.id
      FROM objets o
      INNER JOIN liens LO ON o.id = LO.objets_id
        INNER JOIN personnes p ON LO.personne_id = p.id
      WHERE p.nom = 'A'
    ) t1
    INNER JOIN (
      SELECT o.id
      FROM objets o
      INNER JOIN liens LO ON o.id = LO.objets_id
         INNER JOIN personnes p ON LO.personne_id = p.id
       WHERE p.nom <> 'B'
    ) t2

    A essayer.

  3. #3
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Je suppose qu'un objet peut être lié à plusieurs personnes, sinon la question n'aurait pas de sens...

    Dans ce cas :
    Citation Envoyé par Cinephile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT o.id
    FROM objets o
    INNER JOIN liens LO ON o.id = LO.objets_id
      INNER JOIN personnes p ON LO.personne_id = p.id
    WHERE p.nom <> 'B'
    Ne donne pas les objets qui ne sont pas lié à B...

    Je suppose que la condition doit se représenter par un NOT EXISTS / IN, MINUS, ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT o.id
    FROM objets o
    WHERE id NOT IN (SELECT id
                             FROM liens LO JOIN personnes p 
                                 ON LO.personne_id = p.id
                             WHERE p.nom <> 'B')

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Bon je vous envoie les tests qui ont l'air de fonctionner

    Création des tables avec données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    --
    -- Structure de la table `lien`
    --
     
    CREATE TABLE IF NOT EXISTS `lien` (
      `objet_id` int(11) NOT NULL,
      `personne_id` int(11) NOT NULL,
      PRIMARY KEY  (`objet_id`,`personne_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    --
    -- Contenu de la table `lien`
    --
     
    INSERT INTO `lien` (`objet_id`, `personne_id`) VALUES
    (1, 1),
    (1, 2),
    (2, 1),
    (3, 2);
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `objets`
    --
     
    CREATE TABLE IF NOT EXISTS `objets` (
      `id` int(11) NOT NULL auto_increment,
      `titre` varchar(255) collate utf8_unicode_ci default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
     
    --
    -- Contenu de la table `objets`
    --
     
    INSERT INTO `objets` (`id`, `titre`) VALUES
    (1, 'objet 1'),
    (2, 'objet 2'),
    (3, 'objet 3'),
    (4, 'objet 4');
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `personnes`
    --
     
    CREATE TABLE IF NOT EXISTS `personnes` (
      `id` int(11) NOT NULL auto_increment,
      `nom` varchar(255) collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
     
    --
    -- Contenu de la table `personnes`
    --
     
    INSERT INTO `personnes` (`id`, `nom`) VALUES
    (1, 'auteur'),
    (2, 'auteur exclus');
    On a bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT * FROM objets
    LEFT OUTER JOIN lien
    ON objets.id = lien.objet_id
    LEFT OUTER JOIN personnes
    ON lien.personne_id = personnes.id
    Pour avoir la liste des objets, avec leurs auteurs

    Requête finale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     SELECT *
    FROM objets
    INNER JOIN lien ON objets.id = lien.objet_id
    INNER JOIN personnes ON lien.personne_id = personnes.id
    WHERE nom LIKE 'auteur'
    AND objets.id NOT
    IN (
    SELECT objets.id
    FROM objets
    INNER JOIN lien ON objets.id = lien.objet_id
    INNER JOIN personnes ON lien.personne_id = personnes.id
    WHERE nom LIKE 'auteur exclus'
    )
    ça fait une sous-requête, je pense qu'on perd un peu en performances non ?
    Mais si c'est la seule solution ?

    Nico

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

Discussions similaires

  1. jointure d'une table sur elle même
    Par fred! dans le forum Requêtes
    Réponses: 8
    Dernier message: 25/06/2012, 13h30
  2. Probleme jointure d'une table sur elle même
    Par fred64 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 18/05/2006, 16h01
  3. L'installation d'XP boucle sur elle-même
    Par pf106 dans le forum Windows XP
    Réponses: 13
    Dernier message: 20/08/2005, 15h55
  4. TABLE pointant sur elle-même, requete de selection recursive
    Par Mike@Nestor dans le forum Langage SQL
    Réponses: 1
    Dernier message: 27/07/2005, 15h50
  5. jointure sur une même table
    Par guillaumeVb6 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 06/09/2004, 16h08

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