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 :

Correction d'une requête qui affiche un pourcentage


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut Correction d'une requête qui affiche un pourcentage
    Bonjour,
    Je suis sur Oracle 11g, j'ai la table ELEMENT(ID_ELEMENT, DATE_DEBUT). Le but est d'afficher le pourcentage de la valeur 'null' dans DATE_DEBUT (pourcentage de données manquantes)

    cela fait un moment que je cherche à résoudre un problème avec la requête suivante :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT ((SELECT COUNT( * )FROM ELEMENT WHERE DATE_DEBUT IS NULL)*100 /(SELECT COUNT( * )FROM ELEMENT)) AS PERCENT FROM ELEMENT;

    Elle m'affiche le pourcentage exacte (15,78) mais il est répété plusieurs fois (il est répété le nombre de lignes de la table ELEMENT = 18526) sachant que la donnée n'est pas saisie 2925 fois.
    Nom : 33.PNG
Affichages : 454
Taille : 30,2 Ko

    Ce que je voudrais c'est que ma requête m'affiche ce pourcentage une seule fois sans avoir à le répéter.

    Merci par avance !

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    357
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2008
    Messages : 357
    Points : 417
    Points
    417
    Par défaut
    Bonjour,

    As-tu essayer de rajouter DISTINCT ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT ((SELECT COUNT( * )FROM ELEMENT WHERE DATE_DEBUT IS NULL)*100 /(SELECT COUNT( * )FROM ELEMENT)) AS PERCENT FROM ELEMENT;

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 059
    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 059
    Points : 38 268
    Points
    38 268
    Billets dans le blog
    9
    Par défaut
    attention : comme le diviseur est le résultat d'un sélect, il faut penser à gérer le cas de nullité et de résultat égal à zéro (ne utilisant case when...)

  4. #4
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par David2304 Voir le message
    Bonjour,

    As-tu essayer de rajouter DISTINCT ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT ((SELECT COUNT( * )FROM ELEMENT WHERE DATE_DEBUT IS NULL)*100 /(SELECT COUNT( * )FROM ELEMENT)) AS PERCENT FROM ELEMENT;
    Parfait ! j'ai pas cru que ça fonctionnera ici. Merci beaucoup

  5. #5
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    attention : comme le diviseur est le résultat d'un sélect, il faut penser à gérer le cas de nullité et de résultat égal à zéro (ne utilisant case when...)
    Merci pour la remarque !!

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 792
    Points : 34 013
    Points
    34 013
    Billets dans le blog
    14
    Par défaut
    Comme en fait vous faites une opération sur le résultat de deux SELECT mais que vous n'extrayez pas de lignes d'une table, je pense que c'est plus simple, logique et tout aussi fonctionnel ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT
    (
    	SELECT COUNT(*) 
    	FROM ELEMENT
    	WHERE DATE_DEBUT IS NULL
    )
    * 100
    /
    (
    	SELECT COUNT(*)
    	FROM ELEMENT
    )
    AS PERCENT
    FROM DUAL
    Pour reprendre la remarque d'escartefigue, en supposant bien sûr que la table ELEMENT n'est pas vide.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Merci d'avoir proposé cette réponse, elle fonctionne bien et sans doublons ! Pouvez-vous m'expliquer l’intérêt/fonctionnement de la table DUAL dans cet exemple ?

  8. #8
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Sur Oracle le FROM est obligatoire, d'où l'utilisation de la table dual (une table d'1 ligne et 1 colonne) disponible.
    La démultiplication des lignes provient du dernier appel à la table ELEMENT.

    Une autre approche sans dual est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT sum(case when DATE_DEBUT IS NULL then 1 end) * 100 / COUNT(*)
      FROM ELEMENT

  9. #9
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup pour l'explication !! pour la proposition de la requête elle fonctionne bien aussi !

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 811
    Points
    17 811
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Une autre approche sans dual est
    Oui !
    Mais on peut encore rationaliser la demande, qui est une simple moyenne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select avg(case when date_debut is null then 1 else 0 end) * 100 as percent
      from element;

  11. #11
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 792
    Points : 34 013
    Points
    34 013
    Billets dans le blog
    14
    Par défaut
    Bravo Waldar ! Je n'avais pas interprété le besoin comme une moyenne.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  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
    Bonjour,

    On peut aussi utiliser les count avec la colonne voulue pour ne pas compter les NULL. On obtient alors le pourcentage de non null, qu'il faut soustraire à 100 pour obtenir le pourcentage de NULL

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT 100 - 100. * COUNT(date_debut ) / COUNT(*) AS Pourcentage
    FROM element
    On peux aussi utiliser NULLIF pour gérer le cas de la division par zéro si la table est vide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT 100 - 100. * COUNT(date_debut ) / NULLIF(COUNT(*),0) AS Pourcentage
    FROM element

  13. #13
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Merci pour tout le monde, ce que je voudrais en suite c'est de calculer ces pourcentages par les valeurs suivantes d'une colonne qui s appelle cd_service : 'FI', 'FC', 'RI' sans avoir à récrire la requête 3 fois, j'ai donc essayé avec la requête suivante mais qui me retourne un résultat null !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT CD_SERVICE, 
    ((SELECT COUNT( * )FROM ELEMENT  WHERE ELEMENT.IND_RECONDUITE IS NULL AND CD_SERVICE = 'FI' AND CD_SERVICE ='FC' AND CD_SERVICE = 'RI')*100 /
    (SELECT NULLIF(COUNT( * ),0) FROM ELEMENT WHERE CD_SERVICE = 'FI' AND CD_SERVICE ='FC' AND CD_SERVICE = 'RI')) 
    AS PERCENT FROM ELEMENT WHERE CD_SERVICE IN ('FI','FC','RI') ORDER BY CD_SERVICE;
    quelqu un aura une idée ? =)

  14. #14
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE CD_SERVICE = 'FI' AND CD_SERVICE ='FC' AND CD_SERVICE = 'RI'
    c'est impossible de réaliser cette condition

  15. #15
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par bstevy Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE CD_SERVICE = 'FI' AND CD_SERVICE ='FC' AND CD_SERVICE = 'RI'
    c'est impossible de réaliser cette condition
    d'après ce que je comprends je n'ai que utiliser un sql dynamique ou faire des unions à chaque fois ?

  16. #16
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    UNION est une solution...

    vous pouvez peut etre faire des group by aussi, non ?

  17. #17
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par bstevy Voir le message
    UNION est une solution...

    vous pouvez peut etre faire des group by aussi, non ?
    je l'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT DISTINCT CD_SERVICE,((SELECT COUNT( * )FROM ELEMENT  WHERE IND_EVALUATION IS NULL )
    *100 /(SELECT COUNT( * )FROM ELEMENT )) AS Libelle FROM ELEMENT ORDER BY CD_SERVICE;
    mais ça me retourne le meme pourcentage répété par chaque CD_SERVICE
    FI : 30%
    FC : 30%
    RI : 30%
    .....

    ajoutant que mon interê est de sélectioner que les FI,FC, RI car y en a bien d autres valeurs !

  18. #18
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    quand j'ajoute l'union :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    12345
    (SELECT DISTINCT ((SELECT COUNT( * )FROM ELEMENT  WHERE IND_EVALUATION IS NULL AND CD_SERVICE = 'FI')
    *100 /(SELECT COUNT( * )FROM ELEMENT WHERE CD_SERVICE = 'FI' )) AS FI FROM ELEMENT)
    UNION
    (SELECT DISTINCT ((SELECT COUNT( * )FROM ELEMENT  WHERE DATE_DEBUT IS NULL AND CD_SERVICE = 'FC')
    *100 /(SELECT COUNT( * )FROM ELEMENT WHERE CD_SERVICE = 'FC')) AS FC FROM ELEMENT );
    et le résultat s'affiche en terme de ligne en ne mentionnant que 'FI' :

    FI
    12.25%
    30.23%

  19. #19
    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
    En effet, un simple GROUP BY devrait suffire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    SELECT CD_SERVICE ,  100 - 100. * COUNT(date_debut ) / NULLIF(COUNT(*),0) AS Pourcentage
    FROM element
    WHERE CD_SERVICE IN ('FI','FC','RI') 
    GROUP BY CD_SERVICE

  20. #20
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 30
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2015
    Messages : 23
    Points : 12
    Points
    12
    Par défaut
    @bstevy merci bcp pour votre réponse j'ai fait Order by au lieu de Group by --'

Discussions similaires

  1. Réponses: 7
    Dernier message: 12/03/2015, 07h23
  2. Réponses: 1
    Dernier message: 04/07/2013, 11h23
  3. Résultat d'une requête qui n'affiche rien
    Par LOBO1986 dans le forum JDBC
    Réponses: 6
    Dernier message: 23/01/2013, 13h58
  4. [MySQL] Résultat d'une requête qui ne s'affiche pas
    Par zola013 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 12/08/2010, 19h44
  5. [MySQL] Afficher une date correctement après une requête
    Par Nerva dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 12/04/2006, 17h27

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