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 :

LEFT JOIN et MAX(DATE) ?


Sujet :

Langage SQL

  1. #1
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut LEFT JOIN et MAX(DATE) ?
    Bonjour,

    Je construit une requête devant me lister tous les utilisateurs d'un contrat et s'il y en a eu, leur dernier rendez-vous.
    J'ai donc une table Utilisateurs et une table RDV.

    J'ai grossièrement cette requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT A.ID, A.Nom, A.Prenom, A.Adresse, A..., B.DateRdv, B.Raison, B.Medecin, B....
    FROM USERS A
    LEFT JOIN RDV B ON A.IdUser=B.IdUser

    Là, pas de soucis, j'ai ma liste des utilisateurs et leurs rendez-vous, s'il y en a eu. Maintenant je n'arrive pas à sélectionner uniquement leur dernier RDV.

    J'ai bien essayé ça :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT A.IdUser, A.Nom, A.Prenom, A.Adresse, A..., B.DateRdv, B.Raison, B.Medecin, B....
    FROM USERS A
    LEFT JOIN RDV B ON A.IdUser=B.IdUser
    WHERE B.DateRdv= (SELECT MAX(DateRdv) FROM RDV WHERE IdUser=A.IdUser)

    Mais ça me sort la liste des utilisateurs ayant eu un RDV ainsi que leur dernier RDV. Ce qui n'est pas exactement ce que je souhaite...

    Dans ma sous-requête récupérant la MAX(DateRdv) j'ai bien essayé IdUser=B.IdUser, en pensant qu'il "sélectionnerait" les Id présent dans la table RDV mais ça n'a pas fonctionné non plus.

    Je précise que pour des raisons de confidentialité j'ai reproduit le cas de figure, ma requête est plus complexe que cela et doit potentiellement ramener des milliers de lignes de résultat, je cherche donc quelque chose d'assez optimisé.

    Si ce n'est pas assez précis ou autre, je reste dispo

    En espérant pouvoir résoudre ce cas assez classique, sachez que Google n'a su m'aider, aucune solution trouvé sur le web n'a fonctionné (ou j'ai dû mal appliquer).

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 129
    Points : 38 540
    Points
    38 540
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Utilisez un test d'existence (il n'existe pas de rendez-vous plus récent pour la personne) et le tour est joué

    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
    SELECT A.IdUser,  
           A.Nom, 
           A.Prenom, 
           A.Adresse, 
           A..., 
           B.DateRdv, 
           B.Raison, 
           B.Medecin, 
           B....
    FROM USERS A
    LEFT JOIN RDV B 
      ON B.IdUser=A.IdUser
    WHERE Not exists
         (select 1 from RDV R
          where R.DateRdv > B.DateRdv
            and R.IDUser  = B.IdUser)

  3. #3
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Effectivement cela fonctionne parfaitement, je n'avais pas du tout pensé à ce principe, je cherchais surtout du côté des agrégations mais c'est bien plus simple comme ça.

    Merci beaucoup, sujet clos !

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 147
    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 147
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Et ça ça marche pas ?

    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT A.IdUser, A.Nom, A.Prenom, A.Adresse, A..., B.DateRdv, B.Raison, B.Medecin, B....
    FROM USERS A
    LEFT JOIN RDV B ON A.IdUser=B.IdUser
    AND B.DateRdv= (SELECT MAX(DateRdv) FROM RDV WHERE IdUser=A.IdUser)
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Si cette requête fonctionne, à condition que l'utilisateur ait eu au moins un rendez-vous, hors je voulais une requête externe me retournant NULL si l'utilisateur n'a pas eu de rendez-vous, je ne peux donc pas filtrer sur le MAX(Date) d'une sous-requête. Le test d'existence contourne ce problème, en tout cas pour mon cas de figure.

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 147
    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 147
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Si vous regardez bien, j'ai remplacé le "WHERE" par un "AND".

    A mon avis, cette requête retourne bien ce que vous voulez.
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Membre régulier Avatar de StripMat
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2014
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 206
    Points : 93
    Points
    93
    Par défaut
    Effectivement, c'est une autre solution, j'avais essayé cela mais je m'y étais mal pris. Effectivement si l'on joint la table des RDV sur l'IdUser et la date, si elle est égale à la MAX(Date) pour cet IdUser, on retourne les infos du RDV, sinon vide. C'est bien vu, je pense jamais assez à faire des restrictions dans le FROM quand c'est possible. De plus j'imagine que l'on charge moins de lignes, ça doit être moins gourmand en ressources, enfin j'imagine...

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 129
    Points : 38 540
    Points
    38 540
    Billets dans le blog
    9
    Par défaut
    D'une façon générale, la façon la plus optimisée de faire un test d'existence est d'utiliser exists/not exists

    Mais seul le prototypage dans le contexte qui est le votre permet de s'en assurer

    Après, si vos tables sont peu volumineuses, la différence sera minime, voire non mesurable

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

Discussions similaires

  1. Problème de script SQL : left join et sélection MAX(date)
    Par yoann29200 dans le forum Langage SQL
    Réponses: 13
    Dernier message: 21/01/2016, 15h49
  2. [MySQL-5.5] LEFT JOIN avec MAX qui ne me retourne pas les bonnes données
    Par Gloup dans le forum Requêtes
    Réponses: 4
    Dernier message: 05/05/2014, 17h26
  3. Utiliser MAX() en condition dans un LEFT JOIN
    Par comode dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/05/2012, 21h49
  4. left join avec max(date)
    Par supernicoco dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/10/2008, 08h53
  5. Export d'une vue avec LEFT JOIN
    Par schnourf dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 22/05/2003, 13h57

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