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 :

Problème LEFT JOIN avec conditions ?


Sujet :

Requêtes MySQL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 15
    Par défaut Problème LEFT JOIN avec conditions ?
    Bonjour à tous,

    Je cherche à lister les employés du service S1 qui n'ont pas suivi de formations en 2010. La question semble simple mais impossible de trouver la requête qui va bien

    Mes tables :
    - employes avec les champs : id_employe, nom, service
    - formations avec les champs : id_formation, formation, id_employe, annee

    La requête suivante fournit la liste les employés du service S1 qui n'ont jamais suivi de formations :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT  e.nom, e.service, f.formation, f.annee
    FROM employes e
    LEFT JOIN formations f
    ON e.id_employe = f.id_employe
    WHERE f.formation IS NULL
    AND e.service = 'S1'
    Mais si j'ajoute la condition f.annee = '2010' je n'obtiens plus rien du tout...

    Merci d'avance si quelqu'un a une solution ?

  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 : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Par défaut
    Il faut mettre ta condition dans le ON :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT  e.nom, e.service, f.formation, f.annee
    FROM employes e
    LEFT JOIN formations f
      ON e.id_employe = f.id_employe AND  f.annee = '2010'
    WHERE f.formation IS NULL
    AND e.service = 'S1'

  3. #3
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Bonsoir,

    Donc l'objectif est le suivant:
    Citation Envoyé par Zane Voir le message
    Je cherche à lister les employés du service S1 qui n'ont pas suivi de formations en 2010.
    Il faut travailler en deux étapes:
    - Trouver tous les employés du service S1.
    - Trouver tous les employés ayant suivi une formations en 2010.

    Ensuite il faut faire la différence entre ces deux ensemble avec l'opérateur EXISTS.
    Essayez ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT id_employe, nom
    FROM employes AS e
    WHERE service = 'S1'
    AND NOT EXISTS (
      SELECT *
      FROM formations AS f
      WHERE annee = '2010'
          AND f.id_employe = e.id_employe
    )

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 15
    Par défaut
    C'est vraiment super. Vos deux solutions fonctionnent à merveille. Je n'aurais jamais pensé à ces solutions. Je les ai testées avec MySQL 4.0 et 5.0. La première fonctionne avec les 2 bases, la seconde seulement avec MySQL 5.0.
    Le problème étant classique, je pense qu'il faudrait ajouter ce post dans la FAQ...

    En tout cas félicitations et merci beaucoup

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 15
    Par défaut
    J'ai fait une proposition pour que vos solutions soient ajoutées à la FAQ...
    Encore merci

  6. #6
    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 : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Par défaut
    Citation Envoyé par Zane Voir le message
    J'ai fait une proposition pour que vos solutions soient ajoutées à la FAQ...
    Encore merci
    Merci pour la proposition ! Pour info, la solution d'Oishiiii fonctionne en fait depuis que MySQL accepte les sous-requêtes, donc à partir de la version 4.1.

    Pour la FAQ, je vais corriger directement ton message sur ce point de détail.

  7. #7
    J1
    J1 est déconnecté
    Membre expérimenté Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Par défaut
    Citation Envoyé par Antoun Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT  e.nom, e.service, f.formation, f.annee
    FROM employes e
    LEFT JOIN formations f
      ON e.id_employe = f.id_employe AND  f.annee = '2010'
    WHERE f.formation IS NULL
    AND e.service = 'S1'
    Bonjour,

    attention, faire porter le WHERE sur la colonne f.formation risque de ne pas être significatif si cette colonne est NULLABLE. En effet, si c'est le cas, comment différencier un NULL conséquence du LEFT JOIN d'un NULL stocké dans la table ?
    Il est donc plus sûr de faire porter le WHERE sur une colonne de jointure, comme f.id_employe.

  8. #8
    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 : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Par défaut
    Citation Envoyé par J1 Voir le message
    Bonjour,

    attention, faire porter le WHERE sur la colonne f.formation risque de ne pas être significatif si cette colonne est NULLABLE. En effet, si c'est le cas, comment différencier un NULL conséquence du LEFT JOIN d'un NULL stocké dans la table ?
    Il est donc plus sûr de faire porter le WHERE sur une colonne de jointure, comme f.id_employe.
    +1 !

  9. #9
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    En effet, mais ici il y a un problème de conception.

    Je pense qu'on devrait avoir les tables suivantes (clé primaires soulignées, clé étrangères en italique):

    Service(id_service, libelle)
    Employe(id_employe, nom, id_service)
    Formation(id_formation, libelle)
    Formation_suivi(id_employe, id_formation, annee)

    En supposant qu'un employé appartient à un seul service et qu'il ne peut pas suivre la même formation 2 fois durant la même année.

    Le libellé d'une formation ne peut pas accepter NULL, ça n'a pas de sens.

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

Discussions similaires

  1. Left join avec une condition dans l'autre table
    Par rj450 dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 22/02/2013, 16h50
  2. left outer join avec condition
    Par fisto dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 14/08/2007, 08h52
  3. problème "left join fetch" recup de données associées
    Par ddv_again dans le forum Hibernate
    Réponses: 2
    Dernier message: 19/12/2006, 17h29
  4. Oraclei : LEFT JOIN et conditions
    Par alexadvance dans le forum Oracle
    Réponses: 9
    Dernier message: 02/11/2005, 15h22
  5. LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)
    Par loikiloik dans le forum Langage SQL
    Réponses: 10
    Dernier message: 21/04/2004, 16h38

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