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

MySQL Discussion :

Requête MySQL avec des pourcentages [MySQL-5.6]


Sujet :

MySQL

  1. #1
    Invité
    Invité(e)
    Par défaut Requête MySQL avec des pourcentages
    Bonjour,

    Je cherche à créer une requête en MySQL qui me permette d'avoir les différentes valeurs d'une colonne de DB et, en face, le pourcentage d'occurrences (fréquence) où ces valeurs sont utilisées, le tout trié du plus élevé au moins élevé

    Autrement dit, sur une colonne nommée "sexe_appelant", je voudrais un tri selon la fréquence des valeurs de cette colonne et afficher à côté le pourcentage qui y est lié.

    Un exemple :
    Homme : 65%
    Femme : 30%
    Transgenre : 5%

    Ma requête ici présente fonctionne :

    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select sexe_appelant as "sexe", count(sexe_appelant) as "nombre"
    from appels
    group by sexe_appelant
    order by sexe_appelant;

    Elle me donne :
    Homme : 3
    Femme : 2
    Transgenre : 1

    Mais je ne vois pas comment l'adapter pour avoir des pourcentages... Il faudrait avoir un count de tous les id (= une ligne au lieu de trois) et faire (("nombre"/ce_count_là)*100)... Mais je ne vois pas comment y arriver. C'est peut-être une sous-requête qu'il faut faire, je ne sais plus comment m'y prendre.

    Par ailleurs, je me demande s'il est mieux de faire cette requête complète en MySQL ou s'il vaut mieux la laisser comme telle, et gérer le reste en PHP.
    C'est quoi le moins lourd? Quelle solution sera la moins susceptible de dégrader les perfs de l'appli?

    Merci d'avance !

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Comme vous etes sous MySQL, vous ne pouvez pas utiliser de CTE, mais vous pouvez faire comme ceci :
    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
    SELECT SUM(TT.NBR01)  as Hommes                              
          ,SUM(TT.NBR02) as Femmes                                
          ,SUM(TT.NBR03) as Transg
          ,SUM(TT.NBTOT) as Total   
          ,(SUM(TT.NBR01)*100/SUM(TT.NBTOT))  as P1
          ,(SUM(TT.NBR02)*100/SUM(TT.NBTOT))  as P2
          ,(SUM(TT.NBR03)*100/SUM(TT.NBTOT))  as P3
    FROM (                                              
          SELECT CASE                                   
                 WHEN sexe_appelant='1' THEN 1 END AS NBR01  
                ,CASE                                   
                 WHEN sexe_appelant='2' THEN 1 END AS NBR02  
                ,CASE                                   
                 WHEN sexe_appelant='3' THEN 1 END AS NBR03  
                ,1 AS NBTOT           
          FROM APPELS) AS TT                         
     ;

  3. #3
    Invité
    Invité(e)
    Par défaut
    Wouaw, quelle requête monstrueuse ! Merci escartefigue !

    Et donc, d'après vous, il vaut mieux faire une requête complexe comme celle que vous proposez, ou bien se contenter de mon machin ridicule et terminer le traitement en PHP ?
    Pour le moment, j'ai privilégié la 2e solution par facilité. Au niveau performances, quelle solution est la moins susceptible de dégrader les perfs?

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Vu qu'il n'y a aucun filtrage (pas de where) et que de toutes façons la colonne sexe_appelant ne peut prendre que 3 valeurs, aucun index ne sera utilisé
    Du coup, la sous-requete s'exécutera très probablement par un table-space scan

    Si votre table contient des dizaines de millions voire des milliards d'individus, ça peut être, long, mais vous ne pouvez y échapper.

    La requete qui encapsule par contre devrait être très rapide puisqu'elle n'exploite que les 3 lignes résultantes de la sous-requête, donc si c'est celle là que vous suggérez de traiter par php, ça ne présente pas d'intérêt d'un point de vu perfs, ça peut en avoir d'un point de vue présentation.

    Si mes réponses ont pu vous rendre service, votez en conséquence

  5. #5
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 378
    Points : 19 054
    Points
    19 054
    Par défaut
    Salut à tous.

    C'est mieux quand on teste la requête !

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `appels`
    --------------
     
    --------------
    CREATE TABLE `appels` (
      `id`            integer unsigned NOT NULL auto_increment,
      `sexe_appelant` integer unsigned NOT NULL,
      PRIMARY KEY(`id`)
    )
    --------------
     
    --------------
    insert into `appels` (`sexe_appelant`) values
    (1),(2),(3),(1),(2),(1)
    --------------
     
    --------------
    select * from appels
    --------------
     
    +----+---------------+
    | id | sexe_appelant |
    +----+---------------+
    |  1 |             1 |
    |  2 |             2 |
    |  3 |             3 |
    |  4 |             1 |
    |  5 |             2 |
    |  6 |             1 |
    +----+---------------+
    --------------
    select sum(case when sexe_appelant = 1 then 1 else 0 end) as 'homme',
           sum(case when sexe_appelant = 2 then 1 else 0 end) as 'femme',
           sum(case when sexe_appelant = 3 then 1 else 0 end) as 'autre',
           sum(case when sexe_appelant = 0 then 0 else 1 end) as 'total'
    from appels
    --------------
     
    +-------+-------+-------+-------+
    | homme | femme | autre | total |
    +-------+-------+-------+-------+
    |     3 |     2 |     1 |     6 |
    +-------+-------+-------+-------+
    --------------
    select concat((homme / total) * 100, '%') as 'homme',
           concat((femme / total) * 100, '%') as 'femme',
           concat((autre / total) * 100, '%') as 'autre'
    from (
           select sum(case when sexe_appelant = 1 then 1 else 0 end) as 'homme',
                  sum(case when sexe_appelant = 2 then 1 else 0 end) as 'femme',
                  sum(case when sexe_appelant = 3 then 1 else 0 end) as 'autre',
                  sum(case when sexe_appelant = 0 then 0 else 1 end) as 'total'
           from appels
    ) as x
    --------------
     
    +----------+----------+----------+
    | homme    | femme    | autre    |
    +----------+----------+----------+
    | 50.0000% | 33.3333% | 16.6667% |
    +----------+----------+----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

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

Discussions similaires

  1. [MySQL] Mettre des conditions dans une requête mysql avec pdo
    Par shima5 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 07/10/2010, 21h11
  2. Intégrer requête MySQL avec des CSS
    Par bruno7619 dans le forum Langage
    Réponses: 6
    Dernier message: 25/05/2009, 09h15
  3. [MySQL] Requête mysql avec des variables $_sessions
    Par lavande4 dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 11/09/2008, 20h37
  4. Réponses: 3
    Dernier message: 16/12/2006, 12h59
  5. syntaxe requete mysql avec des variables
    Par harlock59 dans le forum Requêtes
    Réponses: 2
    Dernier message: 29/09/2006, 17h53

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