Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/09/2011, 16h24   #1
Invité de passage
 
Homme Alexandre
Inscription : septembre 2011
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Alexandre

Informations forums :
Inscription : septembre 2011
Messages : 13
Points : 3
Points : 3
Par défaut Calcul de pourcentage via Select imbriqués

Bonjour,

Je suis débutant en SQL, et je travaille sur une table "maison" pour apprendre les bases.

j'ai donc une table MySQL (table_chris), contenant des enregistrements, avec, pour faire simple :
une colonne ID de type integer clé primaire
une colonne outcome_code de type integer
une colonne vendeur de type string


J'ai des enregistrements du type :
Id Vendeur Outcome
------------------------
1 Toto 21
2 Tata 22
3 Tutu 51
4 Toto 22
5 Toto 51
6 Tata 22
7 Toto 22
8 Toto 21
9 Tata 21

Je souhaite calculer, pour chacun des vendeurs, le pourcentage d’occurrence de chaque outcome code.

J'ai donc un premier SELECT
Code :
1
2
3
SELECT Vendeur,COUNT(outcome_code) AS Tot_outcome
            FROM schema_chris.table_chris
            GROUP BY Vendeur

qui me calcule bien, par vendeur, le nombre d'outcome code, qui me permettrait derrière une division du décompte de chaque outcome par ce tot_outcome.

Ensuite, j'imbrique cette requête dans ma requête globale :
Code :
1
2
3
4
5
6
SELECT Vendeur,outcome_code, COUNT(outcome_code),Tot_outcome,COUNT(outcome_code)/Tot_outcome
FROM (SELECT Vendeur,COUNT(outcome_code) AS Tot_outcome
            FROM schema_chris.table_chris
            GROUP BY Vendeur) Tot
GROUP BY Vendeur,outcome_code
ORDER BY Vendeur,outcome_code;
Là, ça ne marche pas, pour la simple et bonne raison que outcome_code n'existe pas dans la sous table tot créée.

Alors j'ai rajouté les champs dans ma sous table :

Code :
1
2
3
4
5
6
SELECT Vendeur,outcome_code, COUNT(outcome_code),Tot_outcome,COUNT(outcome_code)/Tot_outcome
FROM (SELECT Vendeur,outcome_code, COUNT(outcome_code) AS Tot_outcome
            FROM schema_chris.table_chris
            GROUP BY Vendeur) Tot
GROUP BY Vendeur,outcome_code
ORDER BY Vendeur,outcome_code;
ce qui a le mérite de donner un résultat, mais qui n'est pas celui recherché.

Existe-t-il donc un moyen d'y arriver uniquement à partir de SELECT imbriqués, ou faut-il utiliser des choses que je ne connais pas encore (ie toute fonction différente de SELECT, ORDER, GROUP, FROM )
_Tido_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2011, 17h38   #2
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Peut-être en faisant une jointure sur ta sous-requête ?

Code :
1
2
3
4
5
6
7
8
9
 
SELECT test.vendeur, test.outcome, tot.tot_oucome, COUNT(*) nb_outcome, (COUNT(*) * 100) / tot.tot_oucome pourcent
FROM test
INNER JOIN (
SELECT vendeur, COUNT(*) tot_oucome
FROM test
GROUP BY vendeur
) tot ON tot.vendeur = test.vendeur
GROUP BY test.vendeur, test.outcome, tot.tot_oucome;
Code :
1
2
3
4
5
6
7
8
9
10
11
 
vendeur outcome     tot_oucome  nb_outcome  pourcent
------- ----------- ----------- ----------- -----------
Tata    21          3           1           33
Tata    22          3           2           66
Toto    21          5           2           40
Toto    22          5           2           40
Toto    51          5           1           20
Tutu    51          1           1           100
 
(6*ligne(s) affectée(s))
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2011, 19h01   #3
Invité de passage
 
Homme Alexandre
Inscription : septembre 2011
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Alexandre

Informations forums :
Inscription : septembre 2011
Messages : 13
Points : 3
Points : 3
Merci StringBuilder !

Comme je le disais, j'essaye d'apprendre à bien faire, en prenant les concepts les uns après les autres.

Je viens de regarder ce que tu me proposes, et ça fait bien ce que je souhaite faire.
Par contre, peux-tu me confirmer qu'il est impossible, ou alors très mal venu de faire ce que j’attends avec uniquement des SELECT FROM et GROUP, il faut impérativement ajouter un JOIN (qui comme son nom doit l'indiquer permet de travailler avec n tables différentes, en spécifiant ce qu'il y a de commun dans les tables, ici les vendeurs) ?
_Tido_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 08h04   #4
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
En utilisant la clause "over partition" ça doit être faisable.
http://msdn.microsoft.com/fr-fr/library/ms189461.aspx

Mais personnellement, j'ai beaucoup de mal avec cette syntaxe.

Vu ton besoin, la forme "classique" ne fait rien perdre en termes de performances ou de lisibilité (ou presque).
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 09h48   #5
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 431
Points : 6 431
Puis vu qu'il est sous MySQL, qui ne dispose pas des fonctions de fenêtrage, autant oublier tout-de-suite cette possibilité...
Quant à la dégradation des performances, tout dépend de la version de MySQL utilisée. Avant la 5.5, les perfs se dégradent très vite avec la volumétrie pour des sous-requêtes.
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 11h52   #6
Invité de passage
 
Homme Alexandre
Inscription : septembre 2011
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Alexandre

Informations forums :
Inscription : septembre 2011
Messages : 13
Points : 3
Points : 3
Merci à vous deux.

Je souhaitais effectivement rester sur des fonctions classiques et communes de SQL. J'ai pas pour but de devenir un spécialiste, je souhaite juste avoir une connaissance superficielle de SQL avant de m'interesser aux cubes, à l'olap...

J'utilisais MySQL car j'avais déjà une bdd SQL Server sur ma machine, et que je ne voulais pas trop faire des manip' dessus.

Encore merci
_Tido_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 12h44   #7
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Outre les spécificités de Microsoft SQL Server que je t'invite à ignorer, je te conseille cependant de créer une nouvelle base de test sur SQL Server pour apprendre le SQL.

En effet, MySQL n'a qu'un support partiel de la norme SQL. SQL Server en supporte bien plus (les fonctions de fenêtrage en sont un exemple).

Tu apprendras donc mieux à travailler en SQL avec SQL Server je pense.

D'autant que si tu as SQL Server sur ton poste, j'imagine que tu vas devoir travailler avec... donc autant de faire la main dessus et découvrir ses fonctionnalités qui lui sont propre plutôt que celles de MySQL, qui pourrait ne pas te servir au final.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 15h24   #8
Invité de passage
 
Homme Alexandre
Inscription : septembre 2011
Messages : 13
Détails du profil
Informations personnelles :
Nom : Homme Alexandre

Informations forums :
Inscription : septembre 2011
Messages : 13
Points : 3
Points : 3
Mon idée est de faire un mémoire, orienté Marketing, sur les outils de BI Open Source.

En fait, j'ai une bdd sql server sur mon poste qui collecte l'ensemble des calculs de simulation numérique que je fais.
J'ai du mal à y accéder sur mon poste de travail car je dois utiliser un login windows... que ça ne marche pas, et ça devient impossible via Talend.
Comme je ne veux pas alerter tout le monde au bureau que je fais autre chose que mon vrai métier, j'ai donc préféré utilisé MySQL avec SQL Workbench, histoire de ne pas perdre un temps fou à paramétrer.

Je n'ai vraiment pas pour vocation de devenir un expert en SQL, mais vu que j'aime bien savoir de quoi je parle, je me dis que c'est mieux d'avoir des connaissances des bases, de sql, de pourquoi on utilise des cubes,... d'où mon apprentissage simultané de TOS, SQL et iReport

je vais donc suivre en partie ton conseil et installer PostgreSQL (encore une fois, paramétrer mes accès à la bdd et à sql server me parait bien trop long par rapport au temps que j'ai à ma dispo).

un grand merci en tout cas pour ton aide et tes conseils.
_Tido_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h53.


 
 
 
 
Partenaires

Hébergement Web