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 :

problème count avec la valeur 0


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 40
    Points : 26
    Points
    26
    Par défaut problème count avec la valeur 0
    Bonjour,

    dans ma table, je cherche à compter le nombre de personne lorsqu'une étape est validée (validation=true). Le résultat de la requête devrait être :

    personne étape
    personne1 5
    personne2 3
    personne3 4

    J'ai utilisé cette requête :
    SELECT carte.nomEtudiant, Count(carte.idSequence) AS nbSeqValide
    FROM carte
    GROUP BY carte.nomEtudiant, carte.validation
    HAVING carte.validation=true;


    Elle plante quand il n'y a pas d'enregistrement où validation=true (ce qui est normal). Le SGBD ne renvoie pas 0.

    J'ai alors utilisé la requête suivante en imbriquant un SELECT
    SELECT carte.nomEtudiant
    (SELECT COUNT (carte.idSequence) FROM carte WHERE validation=true) AS nbSeqValide
    FROM carte
    GROUP BY nomEtudiant, validation;

    Cette requête renvoie bien 0 quand il n'y a pas d'enregistrement où validation=true. Par contre, le problème c'est que je n'arrive plus à compter pour chaque personne. Est-ce que quelqu'un saurait comment compter les étapes réalisées pour chaque personne ?

    Merci d'avance

    Cristol

  2. #2
    Xo
    Xo est déconnecté
    Expert confirmé
    Avatar de Xo
    Inscrit en
    Janvier 2005
    Messages
    2 701
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 701
    Points : 4 238
    Points
    4 238
    Par défaut Re: problème count avec la valeur 0
    Salut, et bienvenue sur ce forum,

    Primo, tu n'es pas obligé de préfixer tous tes noms de champs par le nom de table, cela n'est utile que si plusieurs des tables ont des champs de même noms, auquel cas le SGBD te demande de déterminer l'appartenance du champ à une table.

    Dans ton cas, tu utilises 2 fois la même table : il faut indiquer dans ta sous-requête que tu ne comptes que les enregistrements de l'étudiant concerné, donc utiliser les alias (ici A et B) pour le jointure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT A.nomEtudiant 
     (SELECT COUNT (b.idSequence)  
        FROM carte b 
       WHERE b validation=true 
         AND A.nomEtudiant = B.nomEtudiant) AS nbSeqValide
    FROM carte A
    GROUP BY nomEtudiant, validation;
    "Ce que l'on conçoit bien s'énonce clairement,
    Et les mots pour le dire arrivent aisément." Nicolas Boileau

    "Expliquer empêche de comprendre si cela dispense de chercher"

    Quiz Oracle : venez tester vos connaissances !

    La FAQ Oracle : 138 réponses à vos questions
    Aidez-nous à la compléter

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Salut Xo

    Merci pour ta réponse. La requête fonctionne à présent :

    SELECT carte.nomEtudiant
    (SELECT COUNT (carte1.idSequence)
    FROM carte1
    WHERE carte1.validation=true AND carte.nomEtudiant =carte1.nomEtudiant) AS nbSeqValide
    FROM carte
    GROUP BY nomEtudiant, validation;



    Par contre, j'ai dû créer une nouvelle table (carte1) en copiant-collant ma table déjà créée. Je crois que ce n'est pas la bonne manière de faire. En fait, peut-on créer une table juste le temps de faire la requête ?

    Merci d'avance !!!

    Cristol

  4. #4
    Xo
    Xo est déconnecté
    Expert confirmé
    Avatar de Xo
    Inscrit en
    Janvier 2005
    Messages
    2 701
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 701
    Points : 4 238
    Points
    4 238
    Par défaut
    Citation Envoyé par cristolb
    Par contre, j'ai dû créer une nouvelle table (carte1) en copiant-collant ma table déjà créée. Je crois que ce n'est pas la bonne manière de faire.
    Argh, si je puis me permettre ... Non, effectivement, ce n'est pas la bonne manière de faire, si tu dois dupliquer une table pour faire une requête, tes procédures vont êtres lourdes à mettre en place . La requête que je t'avais fourni ne fonctionnait-elle pas ? Les alias (A et B) servent justement (entres autres usages) à faire appel à la même table plusieurs fois dans la même requête.

    [Edit] : il manquait un point dans ma requête, la revoilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT A.nomEtudiant 
     (SELECT COUNT (B.idSequence)  
        FROM carte B 
       WHERE B.validation=true 
         AND A.nomEtudiant = B.nomEtudiant) AS nbSeqValide
    FROM carte A
    GROUP BY nomEtudiant, validation;
    [/Edit]
    "Ce que l'on conçoit bien s'énonce clairement,
    Et les mots pour le dire arrivent aisément." Nicolas Boileau

    "Expliquer empêche de comprendre si cela dispense de chercher"

    Quiz Oracle : venez tester vos connaissances !

    La FAQ Oracle : 138 réponses à vos questions
    Aidez-nous à la compléter

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Merci Xo

    Je n'avais pas bien compris comment fonctionnaient les alias. En effet si j'avais dû dupliquer la table, ça aurait été plus que compliqué !
    Voici donc ma requête qui fonctionne bien :

    SELECT carte.nomEtudiant
    (SELECT COUNT (carte1.idSequence)
    FROM carte AS carte1
    WHERE carte1.validation=true AND carte.nomEtudiant =carte1.nomEtudiant) AS nbSeqValide
    FROM carte AS carte
    GROUP BY nomEtudiant;


    Merci pour ton aide rapide !

    Cristol

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    J'ai suivi le sujet depuis le début et comme je ne connais pas l'intérêt & le fonctionnement de l'imbrication de SELECT j'ai du mal à comprendre pourquoi ça marche.

    Vous auriez pas un lien ou quelques explications à m'apporter pour m'éclairer ?

    Thanks.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  7. #7
    Xo
    Xo est déconnecté
    Expert confirmé
    Avatar de Xo
    Inscrit en
    Janvier 2005
    Messages
    2 701
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 701
    Points : 4 238
    Points
    4 238
    Par défaut
    Citation Envoyé par Magnus
    Vous auriez pas un lien ou quelques explications à m'apporter pour m'éclairer ?
    Voilà le problème (Je suis sous Oracle, le champ Validation est donc un char et pas un booléen) :

    J'ai une table Carte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SQL> CREATE TABLE Carte (idSequence NUMBER(10),
      2                      nomEtudiant VARCHAR2(32),
      3                      validation CHAR(1));
    J'ai des valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SQL> SELECT * FROM Carte;
     
    IDSEQUENCE NOMETUDIANT                      V
    ---------- -------------------------------- -
             1 Magnus                           0
             2 Magnus                           1
             3 cristolb                         0
             4 Xo                               1
    La requête simple de cristolb ne permet pas d'avoir les étudiants n'ayant pas de cartes valides :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SQL> SELECT carte.nomEtudiant, Count(carte.idSequence) AS nbSeqValide
      2  FROM carte
      3  GROUP BY carte.nomEtudiant, carte.validation
      4  HAVING carte.validation='1';
     
    NOMETUDIANT                      NBSEQVALIDE
    -------------------------------- -----------
    Magnus                                     1
    Xo                                         1
    Donc il faut contruire une autre requête ... et là je m'aperçois en testant que mon Group By n'est pas bon ... cristolb, la requête que tu as indiqué fonctionnait ???

    Bref, celle qui suit (avec un DISTINCT plutôt qu'un GROUP BY ... ) ne me pose pas de soucis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SQL> SELECT DISTINCT nomEtudiant,
      2   (SELECT COUNT (B.idSequence)
      3      FROM carte B
      4      WHERE B.validation='1' AND A.nomEtudiant = B.nomEtudiant) AS nbSeqValide
      5  FROM carte A;
     
    NOMETUDIANT                      NBSEQVALIDE
    -------------------------------- -----------
    Magnus                                     1
    Xo                                         1
    cristolb                                   0
    Voilà, j'espère avoir répondu à ton interrogation
    "Ce que l'on conçoit bien s'énonce clairement,
    Et les mots pour le dire arrivent aisément." Nicolas Boileau

    "Expliquer empêche de comprendre si cela dispense de chercher"

    Quiz Oracle : venez tester vos connaissances !

    La FAQ Oracle : 138 réponses à vos questions
    Aidez-nous à la compléter

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Merci vraiment Xo pour toutes ces infos.

    En fait, je ne connaissais pas la syntaxe où il figure des SELECT dans le SELECT principal (ni dans la clause FROM de la requête principal comme l'explique SQLPro sur ce site).

    Maintenant je comprends mieux pourquoi ça marche, par contre, comme toi j'ai une erreur sous ORACLE quand j'utilise la dernière requête que tu as proposé avec la clause GROUP BY => au niveau de "(SELECT COUNT(...)"

    J'en déduis donc que l'on ne peut pas faire de GROUP BY quand l'un des champs est lui même obtenu par un SELECT imbriqué ; je me trompe ou il y un moyen d'y arriver ?
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  9. #9
    Xo
    Xo est déconnecté
    Expert confirmé
    Avatar de Xo
    Inscrit en
    Janvier 2005
    Messages
    2 701
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 701
    Points : 4 238
    Points
    4 238
    Par défaut
    Non, le GROUP BY ne peut fonctionner que si tu as un opérateur d'agrégation sur un champ "au même niveau" que le(s) champ(s) sur le(s)quel(s) tu veux faire le regroupement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT champ1, COUNT (champ2) 
    FROM Table 
    GROUP BY champ1
    Dans notre cas, le COUNT est dans la sous-requête...

    Dans un modèle relationnel un peu plus élaboré, avec une table Personne (nommé ci-dessous Etudiant (idEtudiant, nomEtudiant)) et un champ de la table Carte référençant cette personne (fkEtudiant), on aurait la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT
      idEtudiant, 
      nomEtudiant,
      (SELECT COUNT (idSequence)
         FROM carte
        WHERE validation = '1'
          AND fkEtudiant = idEtudiant) AS nbSeqValide
    FROM Etudiant;
    Sans DISTINCT donc, puisque on lit directement la table Etudiant : pas de doublons sur la personne (contrairement à la dernière requête où le nom était stocké dans la table Carte, et où un étudiant pouvait avoir plusieurs cartes ...)
    "Ce que l'on conçoit bien s'énonce clairement,
    Et les mots pour le dire arrivent aisément." Nicolas Boileau

    "Expliquer empêche de comprendre si cela dispense de chercher"

    Quiz Oracle : venez tester vos connaissances !

    La FAQ Oracle : 138 réponses à vos questions
    Aidez-nous à la compléter

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

Discussions similaires

  1. Problème Deserialize avec une valeur vide dans le xml
    Par mactwist69 dans le forum VB.NET
    Réponses: 9
    Dernier message: 25/09/2014, 08h50
  2. Réponses: 0
    Dernier message: 04/08/2014, 22h28
  3. Problème count avec distinct
    Par freeway57 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/06/2014, 16h07
  4. Problème de Count() avec valeur Max
    Par HelpJulien dans le forum QlikView
    Réponses: 1
    Dernier message: 24/05/2012, 17h11
  5. Problème bizarre avec les valeurs #N/A
    Par laloune dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/11/2008, 19h33

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