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 :

requête LEFT JOIN qui ne réagit pas comme souhaité / attendu (enfin, je crois :-) [MySQL-5.0]


Sujet :

Requêtes MySQL

  1. #1
    Membre actif Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 707
    Points : 215
    Points
    215
    Par défaut requête LEFT JOIN qui ne réagit pas comme souhaité / attendu (enfin, je crois :-)
    Bonjour,

    je fais du sql depuis des années mais je suis tombé sur un cas hier que je n'arrive pas à comprendre !

    voici mon schéma qui met en relation des cétégories et des utilisateurs :

    table : categorie (id_categorie, libellé) :
    1, categ1
    2, categ2
    3, categ3

    table : utilisateur_categorie (id_categorie, id_utilisateur) :
    1, 1
    1, 2

    table : utilisateur (id_utilisateur, prénom)
    1, jean
    2, paul

    Mon but est de faire une requête qui, pour toutes les catégories disponibles, me dit si l'utilisateur paul est associé à cette catégorie ou non.

    Dans mon exemple, je souhaite donc obtenir le jeu suivant :
    libelle catégorie, id_utilisateur
    categ1, null
    categ2, null
    categ3, null

    J'ai donc écrit la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT
      c.libelle
    , u.id_utilisateur
    FROM
      categorie c LEFT JOIN
      utilisateur_categorie uc ON c.id_categorie = uc.id_categorie LEFT JOIN
      utilisateur u ON uc.id_utilisateur = u.id_utilisateur
    WHERE
      u.id_utilisateur = 2 OR 
      u.id_utilisateur IS NULL
    Ce que je ne comprends pas, c'est que la requête ci-dessus me renvoie le jeu de résultat suivant
    categ3, null

    categ1 et categ2 n'apparaissent pas dans la sélection car il existe une entrée dans la table d'association mais qui ne correspond pas à l'utilisateur choisi. Pourtant, je pensais que le LEFT JOIN sélectionnait tous les éléments de la table à gauche du ON même sans correspondance dans la table de droite. Y'a un truc qui m'échappe mais je n'arrive pas à voir quoi...

    Auriez-vous une piste ?

    Merci de votre aide !

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Mon but est de faire une requête qui, pour toutes les catégories disponibles, me dit si l'utilisateur paul est associé à cette catégorie ou non.

    ...

    Dans mon exemple, je souhaite donc obtenir le jeu suivant :
    libelle catégorie, id_utilisateur
    categ1, null
    Euh...
    table : utilisateur_categorie (id_categorie, id_utilisateur) :
    1, 1
    1, 2
    Le résultat devrait être categ1, 2 !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT c.libelle AS categorie,
    	u.id_utilisateur
    FROM categorie c
    LEFT OUTER JOIN utilisateur_categorie uc ON uc.id_categorie = c.id_categorie
    	LEFT OUTER JOIN utilisteur u 
    		ON u.id_utilisateur = uc.id_utilisateur
    		AND u.prenom = 'Paul'
    Vous êtes confronté au cas classique que j'explique dans mon blog.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre actif Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 707
    Points : 215
    Points
    215
    Par défaut
    oups, je me suis trompé dans mon jeu de données...

    ma table d'association est :

    table : utilisateur_categorie (id_categorie, id_utilisateur) :
    1, 1
    2, 1

    Paul n'est associé à aucune catégorie...

    Mais effectivement en ajoutant la restriction à la clause ON ça fonctionne...

    Merci !

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 152
    Points : 7 400
    Points
    7 400
    Billets dans le blog
    1
    Par défaut
    En tout cas, c'est pas un problème de MySQL, je reproduis le comportement avec SQL Server.

    Pour résoudre le problème, il faut filtrer non pas dans le WHERE mais dans le ON :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT
      c.libelle
    , u.id_utilisateur
    FROM
      categorie c LEFT JOIN
      utilisateur_categorie uc ON c.id_categorie = uc.id_categorie LEFT JOIN
      utilisateur u ON uc.id_utilisateur = u.id_utilisateur and u.id_utilisateur = 2

    Et là ça fonctionne parfaitement.
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Oui, StringBuilder, c'est un comportement normal. Voir mon blog.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

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

Discussions similaires

  1. [XL-2013] Condition dans un IF THEN qui ne réagit pas comme d'habitude.
    Par jbellavance dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 19/03/2015, 23h43
  2. export access à excel qui ne marche pas comme souhaité?
    Par kesamba dans le forum VBA Access
    Réponses: 15
    Dernier message: 14/03/2011, 07h54
  3. un left join ne me donne pas le résultat attendu
    Par kikidrome dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 05/12/2008, 16h58
  4. Filtrage au niveau de la requête qui ne fonctionne pas comme prévu
    Par hartecel dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 25/06/2008, 14h06
  5. LEFT JOIN qui marche ? pas normal !
    Par gok6tm dans le forum Requêtes
    Réponses: 7
    Dernier message: 12/11/2007, 20h53

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