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 :

SELECT Count et jointure


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Points : 37
    Points
    37
    Par défaut SELECT Count et jointure
    Bonjour à tous. J'ai 3 tables access:

    tblmembres (mbreID, matricule, nom, prenoms, catID)
    tblcategories(catID, catLibelle, catDescription, catTaux)
    tblcotisations(cotID, cotDate, mbreID, cotmois)

    la première table comprend les informations sur les membres d'une association, la seconde contient les catégories de membres (selon la catégorie du membre il y a un montant a cotiser).

    La dernière enregistre les cotisations faites par un membre (date de la cotisation, le membre concerné, le mois pour lequel il cotise).

    Pour une personne dont on a le matricule, je souhaite avoir sa catégorie, et le nombre total de mois qu'il a cotisé. Voici ma requête:

    SELECT COUNT (t.cotmois) AS TOTAL,m.matricule, m.nom, m.prenoms, c.catID FROM tblmembres m,tblcategories c, tblcotisations t WHERE (m.mbreID=t.mbreID AND m.catID=c.catID AND matricule='123456' GROUP BY t.cotmois
    Mais lorsque j'exécute la requête, je reçois le message "Vous avez essayé d'exécuter une requête ne comprenant pas l'expression spécifiée 'matricule' comme une partie de la fonction d'agrégat"

    Je ne vois pas bien ce qui ne vas pas.
    Si quelqu'un veut bien m'aider pour trouver une solution.

    Merci de votre compréhension

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2009
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 229
    Points : 305
    Points
    305
    Par défaut
    T'as oubli d'ajouter t.cotmois à ta requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      SELECT COUNT(t.cotmois) AS TOTAL,
             t.cotmois, m.matricule, m.nom, m.prenoms, c.catID
        FROM tblmembres m, tblcategories c, tblcotisations t
       WHERE m.mbreID = t.mbreID
         AND m.catID = c.catID
         AND matricule = '123456'
    GROUP BY t.cotmois

  3. #3
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Lorsque tu crées un groupement dans ta requête, ce n'est pas le champ contenu dans le count qu'il faut mettre en agrégat de regroupement.

    Code sql : 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
    19
     
    SELECT COUNT (t.cotmois) AS TOTAL,
           m.matricule,
           m.nom,
           m.prenoms,
           c.catID
    FROM
          tblmembres m,
          tblcategories c,
          tblcotisations t
    WHERE
           m.mbreID  = t.mbreID AND
           m.catID   = c.catID  AND
           matricule = '123456'
    GROUP BY
             m.matricule,
             m.nom      , 
             m.prenoms  ,
             c.catID

    Mais tous les champs qui sont dans le select et qui ne sont pas dans le count.
    Je constate que ta requête n'est pas normée, tu devrais regarder du côté des INNER JOIN. Si tu n'es pas familier avec les jointures normées, je te conseil de regarder ici
    -> http://sqlpro.developpez.com/cours/sqlaz/jointures/

    un très bon tutoriel qui explique bien pourquoi utiliser les jointures et comment s'en servir.

    Cordialement.

  4. #4
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Merci à aguetat et Lyche pour vos reponses.

    J'ai essayer d'ajouter tous les champs qui ne sont pas dans le count comme l'a dit Lyche ety ça marche.

    Pour ce qui est de la normalisation, je suis en ce moment même entrain de lire le tuto.

    Merci infiniment

  5. #5
    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
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Voici un petit cours sur la clause "GROUP BY" :
    http://sqlpro.developpez.com/cours/sqlaz/ensembles/

    Je cite :
    De plus, toutes les colonnes représentées hors des calculs d'agrégation doivent figurer dans la clause GROUP BY.

    Hors ici vous faites un GROUP BY sur t.cotmois, mais dans votre select vous avez "m.matricule, m.nom, m.prenoms, c.catID" qui ne fait pas partie de votre GROUP BY, du coup le SGBD ne sait pas quoi faire


    Pour en revenir à votre requête si vous avez une relation 1-1 entre vos tables tblmembres & tblcategories vous pouvez utiliser "MAX" ou "MIN" pour palier ce problème.

    Sinon il faudra passer par une sous requête.


    De plus veillez à utilisez la nouvelle syntaxe pour les jointures ce sera plus lisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT COUNT (t.cotmois) AS TOTAL, m.matricule, max(m.nom), max(m.prenoms), max(c.catID) 
    FROM tblmembres m
    inner join tblcategories c on m.catID=c.catID 
    inner join tblcotisations t m.mbreID=t.mbreID
    WHERE m.matricule='123456' 
    GROUP BY m.matricule
    J'ai aussi changé votre group by, car à la base vous étiez parti pour faire des groupement sur des mois, alors que vous souhaitez avoir des stats par membre distinct.

    edit: ah bah y a du monde ce matin ^^
    edit 2 : une erreur s'était glissée dans ma requête max(m.matricule) remplacé par m.matricule

  6. #6
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Merci à tous. Après la lecture du tuto et de vos différents postes, j'ai normalisé mon sql.

    Mais j'ai une autre préoccupation.

    Je veux une requête qui ramène nom, prenoms, nombre de mois cotisés pour tous les membres de l'association (qu'ils aient cotisé ou non). Pour ce qui n'ont rien cotisé (donc ne sont pas dans la table tblcotisations) nombre de mois cotisés est zéro.

    J'ai aussi besoin d'un coup de main, car toutes mes tentatives sont vaines

  7. #7
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    Il va te falloir une jointure gauche (ou droite) sur la table des collaborateurs. Tu dois d'abord calculer les cotisations pour tous et relier les tables par les identifiants des collaborateurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT nom    ,
           prenom,
           ISNULL(TotalCotisation, 0)
    FROM
           utilisateurs
           LEFT JOIN ( SELECT idMatricule
                              COUNT(moiscotisation)
                       FROM  cotisation ) cotisation
                ON utilisateur.idMatricule = cotisation.idMatricule;
    Je n'ai fait qu'un exemple, (certains n'aiment pas les sous requêtes comme je l'ai faite, mais je trouve que c'est plutôt efficace).

    Je te laisse le soin de l'adapter à ta requête

    Cordialement.

  8. #8
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Merci Lyche. Je viens d'essayer quelque chose qui donne les résultats que je veux. Mais je ne sais pas si coté normalisation il est bon ou pas !!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select m.mbreID,max(matricule), max(nom) as nom, max(prenoms) as prenoms,max(catLibelle) as categorie,max(quotamontant) as quota, count(t.mbreID) as total  
    from (
           (tblmembres m  INNER JOIN 
                 (tblcategories c INNER JOIN tblquotas q ON q.catID=c.catID) ON m.categorie=c.catID ) 
             LEFT OUTER JOIN tblcotisations t ON m.mbreID=t.mbreID)  GROUP BY m.mbreID

  9. #9
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    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 m.mbreID,
           MAX(matricule)                ,
           MAX(nom)          AS nom      ,
           MAX(prenoms)      AS prenoms  ,
           MAX(catLibelle)   AS categorie,
           MAX(quotamontant) AS quota    ,
           COUNT(t.mbreID)   AS total  
    FROM (
           ( tblmembres m
             INNER JOIN ( tblcategories c
                          INNER JOIN tblquotas q
                                ON q.catID = c.catID )
                   ON m.categorie = c.catID )
             LEFT OUTER JOIN tblcotisations t
                   ON m.mbreID = t.mbreID )
    GROUP BY
             m.mbreID;
    Soigne juste ton indentation et tu verras tu arriveras toi même à voir si c'est aux normes .
    Par contre, je ne comprend pas l'emploi des MAX partout

  10. #10
    Nouveau membre du Club
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Les max que j'utilise c'est par rapport au post de punkoff ci-dessous. Sans les max, je suis obligé de mettre les noms de tous les champs dans le GROUP BY

    Merci pour ton aide

  11. #11
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 790
    Points
    6 790
    Billets dans le blog
    4
    Par défaut
    De rien

  12. #12
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Citation Envoyé par Lynecoln Voir le message
    Les max que j'utilise c'est par rapport au post de punkoff ci-dessous. Sans les max, je suis obligé de mettre les noms de tous les champs dans le GROUP BY
    Et pourtant ce serait mieux dans la mesure où dans cette requête-ci ce sont des dimensions :
    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
    19
    20
      SELECT m.mbreID                    ,
             m.matricule                 ,
             m.nom                       ,
             m.prenoms                   ,
             c.catLibelle    AS categorie,
             q.quotamontant  AS quota    ,
             COUNT(t.mbreID) AS total  
        FROM tblmembres m
             INNER JOIN tblcategories c
               ON m.categorie = c.catID
             INNER JOIN tblquotas q
               ON q.catID = c.catID
             LEFT OUTER JOIN tblcotisations t
               ON t.mbreID = m.mbreID
    GROUP BY m.mbreID      ,
             m.matricule   ,
             m.nom         ,
             m.prenoms     ,
             c.catLibelle  ,
             q.quotamontant;

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

Discussions similaires

  1. SELECT count et Jointure interne
    Par tompalmeras dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 30/04/2010, 14h54
  2. De l'aide pour Jointure, avec selection count =0
    Par onemart dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/01/2009, 09h01
  3. select + count() ou SUM + jointure
    Par gilles974 dans le forum Requêtes
    Réponses: 6
    Dernier message: 31/10/2008, 13h58
  4. Select count avec jointure, en récupérant les 0 : possible ?
    Par littlewings dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/07/2008, 12h57
  5. select count avec jointure, en récupérant les 0
    Par littlewings dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/07/2008, 11h58

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