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 :

[SQL] count() sur plusieurs tables


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2009
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2009
    Messages : 351
    Par défaut [SQL] count() sur plusieurs tables
    Bonjour,

    Je cherche depuis un bon moment comment faire une requête.

    Voici l'énoncé de mon problème :

    J'ai 3 tables qui se présentent comme suit :

    table des négociateur (t_negociateur) :

    negociateur_id | neg_nom

    1 | Dupont
    2 | Durant
    3 | Tartanpion
    ... ...


    table des erreurs sur les offres (check_offres) :

    offre_id | neg_id

    1 | 1
    2 | 2
    3 |3
    4 |1
    5 | 1
    ... ...


    table des erreurs sur les demandes (check_demandes) :

    demande_id | neg_id

    1 | 1
    2 | 2
    3 | 3
    4 | 3
    5 | 2
    ... ...


    Et je voudrai resortir un resultat comme suit :


    nom du négociateur | nombre erreurs offres | nombre erreurs demandes

    Dupont | 64 | 26
    Durant | 31 | 23
    Tartanpion |28 | 37


    Attention : Je voudrais sortir ce résultat en 1 seule requête pour pouvoir faciliter les tris de mon tableau par la suite.

    Merci d'avance de votre aide.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Par défaut
    Bonjour,
    tu joins les 3 tables et tu fais un count(offre) et un count(demande) en groupant par negociateur

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2009
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2009
    Messages : 351
    Par défaut
    Oui c'est ce que j'ai essayé mais le résultat il ne distingue pas le nombre d'erreurs offres du nombre d'erreurs demande.

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    bonjour,

    je vois en gros deux solutions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select a.*,
    (select count(*) from offres b where a.negociateur_id = b.neg_id),
    (select count(*) from demandes c where a.negociateur_id = b.neg_id)
    from negociateur a


    et sinon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select a.negociateur_id, a.neg_nom,
    sum(case when b.neg_id is not null then 1 else 0),
    sum(case when c.neg_id is not null then 1 else 0),
    from negociateur a
    left outer join offres b on a.negociateur_id = b.neg_id
    left outer join demandes c on a.negociateur_id = b.neg_id
    group by a.negociateur_id, a.neg_nom

    A tester les deux solutions pour prendre celle qui a le meilleur plan d'acces.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Je n'aime aucune des deux solutions du dessus !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      SELECT a.neg_nom
           , coalesce(b.nb_off, 0) as nb_off
           , coalesce(c.nb_dmd, 0) as nb_dmd
        FROM negociateur a
             LEFT OUTER JOIN (select neg_id, count(*) as nb_off FROM offres   group by neg_id) b
               ON b.neg_id = a.negociateur_id
             LEFT OUTER JOIN (select neg_id, count(*) as nb_dmd FROM demandes group by neg_id) c
               ON c.neg_id = a.negociateur_id
    ORDER BY a.negociateur_id ASC;

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2009
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2009
    Messages : 351
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Je n'aime aucune des deux solutions du dessus !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      SELECT a.neg_nom
           , coalesce(b.nb_off, 0) as nb_off
           , coalesce(c.nb_dmd, 0) as nb_dmd
        FROM negociateur a
             LEFT OUTER JOIN (select neg_id, count(*) as nb_off FROM offres   group by neg_id) b
               ON b.neg_id = a.negociateur_id
             LEFT OUTER JOIN (select neg_id, count(*) as nb_dmd FROM demandes group by neg_id) c
               ON c.neg_id = a.negociateur_id
    ORDER BY a.negociateur_id ASC;
    Je pense que c'est presque ça mais pas tout à fait car, par exemple pour Tatampion qui a 6 erreurs d'offre et 22 erreurs de demande, j'obtiens le résultat suivant :

    neg_nom | nb_off | nb_dmd

    Tartampion | 6 | 22
    Tartampion | 0 | 0
    Tartampion | 3 | 0

    Je pense que c'est dut au fait que l'id de Tartampion apparait plusieurs fois dans la table t_negociateur. Que dois-je faire pour n'avoir qu'une ligne de résultat par négociateur ?

  7. #7
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 197
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Je n'aime aucune des deux solutions du dessus !
    Personnellement, je préfère la requête avec les sous-select dans la liste des colonnes du select, plutôt que ta solution (moins lisible je trouve).
    De plus, niveau perf, je ne suis pas certain qu'il n'y trouve la moindre différence, puisque les deux font absolument la même chose (au bug près)

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2009
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2009
    Messages : 351
    Par défaut
    J'ai essayé la 2eme solution mais j'obtiens le message suivant :

    Msg*102, Niveau*15, État*1, Ligne*2
    Syntaxe incorrecte vers ')'.

    avant cela j'ai déjà enlevé la virgule après la parenthèse fermante du 2eme SUM parce que j'avais une erreur dessus.

    Autre précision que j'ai oublié dans l'énoncé :

    Je dois aussi vérifier les champs : 'agence_id' et 'neg_actif' de la table t_negociateurs en faisant qqc comme : "WHERE N.agence_id=1 and N.neg_actif = 1" ... je ne pense pas que cela ait une quelconque importance mais je préfère le préciser.

  9. #9
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    ah oui j'ai oublié le end désolé,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT a.negociateur_id, a.neg_nom,
    sum(case when b.neg_id IS NOT NULL then 1 else 0 end),
    sum(case when c.neg_id IS NOT NULL then 1 else 0 end),
    FROM negociateur a
    LEFT OUTER JOIN offres b ON a.negociateur_id = b.neg_id
    LEFT OUTER JOIN demandes c ON a.negociateur_id = b.neg_id
    GROUP BY a.negociateur_id, a.neg_nom
    ceci étant dit, si Waldar dit qu'il préfère sa solution écoutez-le il a dû comparer les plans pour en déduire que sa proposition est meilleur.


    Sinon, vous pouvez rajouter votre clause where sans aucun problème dans les 3 cas cités.

  10. #10
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    voilà la requete qe tu cherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select  t_negociateur.nom_neg,nbre_demande,nbre_offre
    FROM (select count(neg_id) as nbre_demande ,neg_id
    from check_demandes
    group by neg_id)demande  
    RIGHT JOIN (
    (select count(neg_id) as nbre_offre ,neg_id
    from check_offres
    group by neg_id)offre  
    RIGHT JOIN t_negociateur ON offre.neg_id = t_negociateur.negotiateur_id) ON demande.neg_id = t_negociateur.negotiateur_id
    Resulat d'apres l'exemple que tu as donné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    nom_neg	nbre_demande	nbre_offre
    Dupont	             1	3
    Durant	             2	1
    Tartanpion	2	1

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

Discussions similaires

  1. Statistique count sur plusieurs tables
    Par nsanabi dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/03/2009, 11h23
  2. [SQL] SQL Requete sur plusieurs tables/traitement particulier
    Par fluojet dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/02/2007, 19h59
  3. Réponses: 1
    Dernier message: 06/12/2006, 18h25
  4. Count sur plusieurs tables
    Par Remedy dans le forum Langage SQL
    Réponses: 2
    Dernier message: 16/07/2006, 00h41
  5. Réponses: 8
    Dernier message: 17/05/2006, 14h32

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