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 :

Compter une colonne


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut Compter une colonne
    Bonjour à tous ,

    J'ai une table clients, projects et files.

    Je cherche a sortir un tableau du style :

    Nom client | Nombre de projects | Taille total de tous les fichiers des projets du client

    Ma table client est sous cette forme (simplifié)
    • id
    • name


    Ma table projects (simplifié)
    • id
    • name
    • client_id


    ma table files
    • id
    • name
    • size
    • project_id


    Pour le moment voici ce que j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT name, 
    (SELECT COUNT(id) FROM projects WHERE clients.id = projects.client_id) as n_project
    FROM clients
    Ce qui me donne : Nom du client | Nombre de project
    ex:
    Google => 5
    Nike => 2
    etc...

    Et donc j'aimerai avoir la taille des fichiers des projets de chaque clients
    ex:

    Google => 5 => 200

    Soit google à 5 projets et ces projets contiennent x fichiers qui font au total 200 octets


    J’imagine que c'est un truc du genre mais je sèche :/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT id, name, slug, ckey, 
    (SELECT COUNT(id) FROM projects WHERE clients.id = projects.client_id) as n_project, 
    (SELECT SUM(size) FROM files WHERE ?????????? ) as c_size 
    FROM clients

    Merci de m'aider . Bonne journée

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Essayez ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT
        C.name,
        COUNT(DISTINCT P.id) AS NbProjets,
        SUM(F.size) AS TailleTotale
    FROM    Client C
    INNER JOIN Projet P
        ON    P.client_id = C.Id
    INNER JOIN Files F
        ON    F.project_id = P.id
    GROUP BY C.name

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Merci de votre réponse.

    Pour les besoins de l'affichage j'ai changé les noms, mais pas votre structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT
    	c.id as id, c.name as name, c.slug as slug, c.ckey as ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    INNER JOIN Files F
    	ON    F.project_id = P.id
    GROUP BY C.name
    J'ai bien la bonne size des files, mais n_project votre ancien NbProjets renvoie toujours 1 qui est le nombre de project du premier résultat.


    Merci

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    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 103
    Points : 28 400
    Points
    28 400
    Par défaut
    Toutes les colonnes qui ne font pas l'objet d'une fonction de regroupement doivent être mentionnées dans la clause GROUP BY.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT
    	c.id AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    INNER JOIN Files F
    	ON    F.project_id = P.id
    GROUP BY c.id AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey
    La majorité des SGBD, qui respectent les règles de la syntaxe SQL, auraient refusé votre requête.

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    heu...

    Vous avez ajouté des colonnes dans le select mais pas dans le group by...

    Vos requête n'est donc pas correcte, et vous devez être sous MySQL, qui, plutôt que vous remonter une erreur, vous remonte des résultats aléatoires...

    Modifiez le group by

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Vos deux requêtes sans mes ajouts de select retourne quand même 1 en nombre de project

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Que donne cette requête ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT client_id, COUNT(*) AS n_projets
    FROM Projects
    GROUP BY client_id

  8. #8
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    client_id | n_projects
         1     |      1
         2     |      2
    Ce qui est juste le client 1 a 1 project et le client 2 en a deux

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par Hotgeart Voir le message
    Ma table projects (simplifié)
    simplifiée comment ????

    que donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
    FROM Projetcs
    WHERE client_id = 2

  10. #10
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    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 103
    Points : 28 400
    Points
    28 400
    Par défaut
    Et chacun des projets du client 2 a bien des lignes référencées dans Files ?

    Essaye avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT c.id AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    LEFT JOIN Files F
    	ON    F.project_id = P.id
    GROUP BY c.id AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey

  11. #11
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    CREATE TABLE IF NOT EXISTS `clients` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      `slug` varchar(255) NOT NULL,
      `logo` varchar(255) NOT NULL,
      `ckey` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
     
     
    CREATE TABLE IF NOT EXISTS `files` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      `image` varchar(255) NOT NULL,
      `file` varchar(255) NOT NULL,
      `size` int(11) NOT NULL,
      `version` varchar(255) NOT NULL,
      `fdate` date NOT NULL,
      `project_id` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `project_id` (`project_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
     
    CREATE TABLE IF NOT EXISTS `projects` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      `client_id` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `client_id` (`client_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
    Voila l'archi de ma bdd

    @al1_24 Mysql me renvoi ceci : #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey LIMIT 0, 30' at line 9

  12. #12
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Et chacun des projets du client 2 a bien des lignes référencées dans Files ?
    Je crois qu'Al1_24 a vu juste...

    @al1_24 Mysql me renvoi ceci : #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS id, c.name AS name, c.slug AS slug, c.ckey AS ckey LIMIT 0, 30' at line 9

    Enlevez les AS xxx dans le GROUP BY

  13. #13
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Sans les as du code de al1_24 ça marche. Cependant, si un client n'a pas de project il ne s'affiche pas.

    merci pour vos réponses

  14. #14
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par Hotgeart Voir le message
    Cependant, si un client n'a pas de project il ne s'affiche pas.
    Il suffit de faire une jointure externe sur la table projet aussi...

  15. #15
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Bonjour,

    J'essaye encore et encore depuis hier, mais je n'y arrive pas il ne m'affiche jamais cette ligne avec 0 project

    J'ai essayé ces requests et des variantes :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    LEFT JOIN Files F
    	ON    F.project_id = P.id
    RIGHT OUTER JOIN Projects
    	ON    C.id = projects.client_id
    GROUP BY c.id, c.name, c.slug, c.ckey
     
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    LEFT JOIN Files F
    	ON    F.project_id = P.id
    LEFT OUTER JOIN Projects
    	ON    projects.client_id = C.id
    GROUP BY c.id, c.name, c.slug, c.ckey
     
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(DISTINCT P.id) AS n_project,
    	SUM(F.size) AS ClientDisk
    FROM    Clients C
    INNER JOIN Projects P
    	ON    P.client_id = C.Id
    LEFT JOIN Files F
    	ON    F.project_id = P.id
    LEFT JOIN Projects
    	ON    projects.client_id = C.id
    GROUP BY c.id, c.name, c.slug, c.ckey
     
     
    ETC...
    Avec Google, je tombe sur des forums ou on dit qu'une jointure extern doit comporter un OUTER d'autres disent le contraire bref je ne sais plus quoi penser :/ .

    Merci de vos lumières

  16. #16
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    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 103
    Points : 28 400
    Points
    28 400
    Par défaut
    Et comme ça tout simplement, ça ne fonctionne pas ?
    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  c.id    AS id
        ,   c.name  AS name
        ,   c.slug  AS slug
        ,   c.ckey  AS ckey
        ,   COUNT(DISTINCT P.id)    AS n_project
        ,   SUM(F.size)             AS ClientDisk
    FROM    Clients C
        LEFT JOIN Projects P
            ON  P.client_id = C.Id
        LEFT JOIN Files F
            ON  F.project_id = P.id
    GROUP BY c.id
        ,   c.name
        ,   c.slug
        ,   c.ckey
    ;
    PS : pour mieux comprendre les jointures, tu peux aller voir ici

  17. #17
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Pourquoi faire deux jointures sur la table des projets ?

    En supposant qu'un projet ne compte qu'une seule ligne dans la table des projets, combien de projets par client ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(p.id) AS n_project
    FROM Clients c
    LEFT OUTER JOIN Projects p ON p.client_id = c.id
    GROUP BY c.id, c.name, c.slug, c.ckey
    Maintenant j'ajoute la jointure avec les fichiers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(p.id) AS n_project
    FROM Clients c
    LEFT OUTER JOIN Projects p ON p.client_id = c.id
    	LEFT OUTER JOIN Files f ON f.project_id = p.id
    GROUP BY c.id, c.name, c.slug, c.ckey
    Contrairement à ce qu'indique la fonction COUNT, comme il peut y avoir plus d'un fichier par projet, la requête ne compte pas les projets mais les fichiers.
    Pour compter réellement combien il y a de projets, il faut utiliser COUNT(DISTINCT p.id)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(DISTINCT p.id) AS n_project
    FROM Clients c
    LEFT OUTER JOIN Projects p ON p.client_id = c.id
    	LEFT OUTER JOIN Files f ON f.project_id = p.id
    GROUP BY c.id, c.name, c.slug, c.ckey
    Maintenant, je peux calculer la taille totale des fichiers du projet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT c.id, c.name, c.slug, c.ckey,
    	COUNT(DISTINCT p.id) AS n_project,
    	SUM(f.size) AS ClientDisk
    FROM Clients c
    LEFT OUTER JOIN Projects p ON p.client_id = c.id
    	LEFT OUTER JOIN Files f ON f.project_id = p.id
    GROUP BY c.id, c.name, c.slug, c.ckey
    LEFT (ou RIGHT) JOIN ou LEFT OUTER (ou RIGHT) JOIN sont équivalents.
    On peut dire que OUTER est un mot inutile. Il précise juste sémantiquement qu'il s'agit bien d'une jointure externe, par opposition à la jointure interne INNER JOIN. Le mot clé INNER est d'ailleurs, lui aussi, facultatif ; un simple JOIN est une jointure interne.

  18. #18
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 63
    Points : 63
    Points
    63
    Par défaut
    Merci

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

Discussions similaires

  1. compter les colonnes de type varchar d'une base
    Par jcachico dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 18/07/2007, 12h10
  2. Compter dans une colonne le nb de valeurs communes
    Par kenny49 dans le forum Requêtes
    Réponses: 3
    Dernier message: 23/04/2007, 14h48
  3. requete pour compter les valeurs ds une colonne
    Par smariteau dans le forum Requêtes
    Réponses: 2
    Dernier message: 10/02/2006, 17h37
  4. Comment compter les doublons d'une colonne?
    Par Dnx dans le forum Langage SQL
    Réponses: 8
    Dernier message: 07/11/2005, 10h50
  5. Comment compter seulement une valeur d'une colonne
    Par kolac dans le forum Langage SQL
    Réponses: 7
    Dernier message: 28/07/2005, 01h40

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