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 :

Aide sur une requête


Sujet :

Langage SQL

  1. #1
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut Aide sur une requête
    Bonjour,

    Je sollicite votre aide sur une requête que j'ai du mal à écrire.
    J'ai des sociétés qui peuvent avoir des contacts et les contacts peuvent avoir un "dernier résultat".

    Lorsque je modifie le "dernier résultat" d'un contact j'enregistre aussi la date de cette modification.

    Je souhaiterais récupérer la liste de toutes mes sociétés avec, entre autres, le dernier "dernier résultat" s'il y en a.
    J'entend par dernier "dernier résultat" celui dont la date est la plus récente.

    J'y arrive bien pour une société donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT dr.description, c.nom, c.prenom
    FROM societe s
    INNER JOIN contact c ON c.id_societe = s.id
    INNER JOIN dernierresultat dr ON c.id_dernierresultat = dr.id
    WHERE s.id = XX and c.datedr = (SELECT max(c.datedr) 
    				FROM societe s
    				INNER JOIN contact c ON c.id_societe = s.id
    				WHERE s.id = XX);
    Mais pour l'ensemble de mes sociétés celà me semble plus compliqué. Je pourrais faire ça salement en récupérant toutes mes sociétés avec une seule requête et pour chacune d'entre elle exécuter une requête pour savoir s'il y a un dernier résultat ou non et lequel si existant mais c'est vraiment quelque chose que j'aimerais éviter si celà est possible.

    Auriez-vous une idée sur la façon de procéder ?

    Je vous remercie d'avance pour votre aide

    P.S: Désolé pour le titre peu explicite mais je n'arrive pas à synthétiser mon problème en quelques mots.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Voici la requête pour une société, à toi de l'étendre à toutes les sociétés
    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
    SELECT  dr.description
        ,   c.nom
        ,   c.prenom
    FROM    societe s
        INNER JOIN 
            contact c 
            ON  c.id_societe = s.id
        INNER JOIN 
            dernierresultat dr 
            ON  c.id_dernierresultat = dr.id
    WHERE   s.id = XX 
        AND EXISTS
            (   SELECT  1
                FROM    contact c2 
                WHERE   c2.id_societe = s.id
                HAVING  max(c2.datedr) = c.datedr
            )
    ;
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Merci pour ton aide !

    J'ai réussi à étendre le code pour l'ensemble des sociétés mais seules les sociétés ayant un dernier résultat sont présentes dans les résultats. Ce qui d'ailleurs semble logique avec l'utilisation de l'opérateur EXISTS.

    En fait je souhaitais afficher toutes mes sociétés avec des nulls dans la colone "dernier résultat" s'il n'y a rien ou alors le "dernier résultat" s'il existe.
    Sur une jointure j'aurais fait un LEFT OUTER JOIN mais là ce n'est pas vraiment une jointure

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Mais si il s'agit bien d'une jointure avec une vue imbriquée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT dr.description, c.nom, c.prenom, cm.max_datedr
      FROM societe s
           INNER JOIN contact c 
             ON c.id_societe = s.id
           INNER JOIN dernierresultat dr 
             ON dr.id = c.id_dernierresultat
           LEFT OUTER JOIN 
            (  SELECT id_societe, max(datedr) as max_datedr
                 FROM contact
             GROUP BY id_societe  ) cm
             ON cm.id_societe = s.id;

  5. #5
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Mais si il s'agit bien d'une jointure avec une vue imbriquée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT dr.description, c.nom, c.prenom, cm.max_datedr
      FROM societe s
           INNER JOIN contact c 
             ON c.id_societe = s.id
           INNER JOIN dernierresultat dr 
             ON dr.id = c.id_dernierresultat
           LEFT OUTER JOIN 
            (  SELECT id_societe, max(datedr) as max_datedr
                 FROM contact
             GROUP BY id_societe  ) cm
             ON cm.id_societe = s.id;
    Merci pour ton aide.

    Cette fois ci j'ai bien la liste complète des sociétés (à condition de remplacer les INNER JOIN par des LEFT OUTER JOIN) mais dans la requête j'ai l'ensemble des contacts avec leurs "derniers résultats" respectifs plutôt que simplement le dernier "dernier résultat", le "max(datedr)" ne semble pas avoir d'effet.

    En fait la réponse est la combinaison de vos deux requêtes mais mes essais n'ont pas été concluant

    En tous cas j'aurais appris qu'il est possible de faire des jointures sur des résultats de requête

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Oui, j'ai oublié le WHERE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE c.datedr = cm.max_datedr
       OR cm.max_datedr IS NULL

  7. #7
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Là c'est parfait pour les sociétés qui ont des contacts ayant des derniers résultats.
    En revanche pour les sociétés qui ont des contacts n'ayant pas de dernier résultat j'ai autant de ligne pour une seule société qu'il y a de contacts différents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Societe 1 - Contact 1 - Commande passée - 05/10/2009
    Societe 2 - Contact 1 - null - null
    Societe 2 - Contact 2 - null - null
    Societe 2 - Contact 3 - null - null
    Societe 3 - Contact 7 - En attente de confirmation - 09/02/2010
    J'imagine que c'est parce que les lignes incrimiées ne sont pas filtrées par le critère qui impose une égalité ?
    Du coup ce que je demande n'est peut-être pas possible.

    Dans le pire des cas je pourrais toujours post-traiter les données une fois reçue mais la base de données est plus efficace pour faire ce genre de traitement.

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Non non, on va le faire en SQL, j'ai quelques questions pour mieux cerner votre besoin.

    Est-ce que toutes les sociétés ont forcément un contact ?
    Est-ce que la datedr de la table contact peut être nulle ?
    S'il n'y a pas de dernier resultat, vous voulez voir la société mais aucun contact ?

    Dans votre processus, je ne suis pas certain que mettre à jour la colonne contact.datedr en fonction de la table dernierresultat se justifie pleinement.

  9. #9
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    En fait je suis en train de développer un logiciel de CRM (gestion de la relation client) dans lequel j'ai importé un fichier de sociétés (plusieurs milliers).


    Est-ce que toutes les sociétés ont forcément un contact ?
    Non, pas nécessairement. Il est possible de créer une société et de lui ajouter des contacts plus tard.

    Est-ce que la datedr de la table contact peut être nulle ?
    Oui si on n'a fait aucune action avec ce contact (le fichier contient plus de sociétés que de clients réels de la société pour laquelle je suis en stage, donc s'il n'y a eu aucune action de faite avec un contact il n'y a pas de dernier résultat et donc pas de date de dernier résultat.

    S'il n'y a pas de dernier resultat, vous voulez voir la société mais aucun contact ?
    En fait le besoin réel est d'afficher la liste de mes sociétés dans un tableau avec toutes les informations dont je dispose sur elles. Le "dernier résultat" étant un peu spécial parce qu'il n'est pas directement lié à la société mais aux contacts de la société.
    Donc même s'il n'y a pas de dernier résultat je souhaite que ma société soit présente dans mon tableau et je ne mettrais aucune valeur dans la colonne "dernier résultat".

    En réalité je n'ai pas besoin de récupérer le contact ni la date de dernier résultat, j'ai juste besoin du dernier résultat s'il existe ou sinon null. J'ai juste ajouté le contact et dans la date de dernier résultat dans le select pour que les choses soient plus claires pour vous.

    Dans votre processus, je ne suis pas certain que mettre à jour la colonne contact.datedr en fonction de la table dernierresultat se justifie pleinement.
    En fait c'est le seul moyen que j'ai trouvé pour être certain de localiser le dernier des derniers résultats.
    Si tous les contacts ont un dernier résultat (qui peut changer dans le temps), comment puis-je trouver le dernier en date sans savoir quand le champ a été mis à jour ?

    Plus simplement, ce que je souhaite c'est d'avoir une ligne par société. Qu'elle ai des contacts ou non, qu'il y ai des derniers résultats ou non puisqu'au final ce ne sont que des informations complémentaires vis à vis du but de ma requête qui est de charger l'ensemble de mes sociétés.

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Celle-ci devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT s.*, dr.description, c.nom, c.prenom, cm.max_datedr
      FROM societe s
           LEFT OUTER JOIN contact c 
           INNER JOIN 
            (  SELECT id_societe, max(datedr) AS max_datedr
                 FROM contact
             GROUP BY id_societe  ) cm
             ON cm.id_societe = c.id_societe
            AND cm.max_datedr = c.datedr
           INNER JOIN dernierresultat dr 
             ON dr.id = c.id_dernierresultat
             ON c.id_societe = s.id
    En fait c'est le seul moyen que j'ai trouvé pour être certain de localiser le dernier des derniers résultats.
    Si tous les contacts ont un dernier résultat (qui peut changer dans le temps), comment puis-je trouver le dernier en date sans savoir quand le champ a été mis à jour ?
    Vous pouvez utiliser une colonne qui garde la date au niveau de dernierresultat (date de creation et/ou date de mise à jour), après il suffira d'une jointure entre vos deux tables.

  11. #11
    Membre éclairé Avatar de Julien Bodin
    Homme Profil pro
    Devops
    Inscrit en
    Février 2009
    Messages
    474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

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

    Informations forums :
    Inscription : Février 2009
    Messages : 474
    Points : 843
    Points
    843
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Celle-ci devrait fonctionner :
    Vous pouvez utiliser une colonne qui garde la date au niveau de dernierresultat (date de creation et/ou date de mise à jour), après il suffira d'une jointure entre vos deux tables.
    Mais comme plusieurs contacts peuvent avoir le même "dernier résultat" je stocke la date directement dans le contact, c'est ce qui m'a semblé le plus logique.

    Sinon la requête fonctionne parfaitement. De plus ça m'a permis de voir que le SQL pouvait être encore plus souple que ce que j'imaginais Ca m'ouvre de nouvelles perspectives.

    Merci beaucoup pour votre aide

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

Discussions similaires

  1. [SQL] Besoin d'aide sur une requête
    Par Angath dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/01/2006, 16h26
  2. Réponses: 1
    Dernier message: 03/08/2005, 11h41
  3. Besoin d'aide sur une requête (JOIN + COUNT ?)
    Par PanzerKunst dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/06/2005, 10h29
  4. Aide sur une requête
    Par TshAw dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/02/2005, 11h42
  5. Aide sur une requête (Group By...??)
    Par Cocolapin dans le forum Langage SQL
    Réponses: 4
    Dernier message: 12/12/2004, 10h26

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