Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
932 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Moyenne un peu compliquée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Moyenne un peu compliquée

n°1494841
nero27
Posté le 21-12-2006 à 15:14:50  profilanswer
 

Bonjour,

 

Je bloque pour calculer une moyenne alors que ça ne doit pas être si compliqué (en MySQL).

 

En gros, j'ai 2 tables "cochon" et "user" :
Cochon (id_cochon, id_user, ...)
User (id_user, ...)

 

Je voudrais calculer le nombre moyen de cochons par user.

 

Je me doute qu'il faut utiliser la fonction avg, mais je ne vois pas comment :/

 

Merci d'avance :jap:


Message édité par nero27 le 21-12-2006 à 15:15:34
mood
Publicité
Posté le 21-12-2006 à 15:14:50  profilanswer
 

n°1494860
flo850
moi je
Posté le 21-12-2006 à 15:41:14  profilanswer
 

ca devait marcher :

 

SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user  FROM cochon

 

Message cité 1 fois
Message édité par flo850 le 21-12-2006 à 15:41:23
n°1494906
polo021
Posté le 21-12-2006 à 16:25:25  profilanswer
 

select avg(cnt) from select count(*) as cnt from cochon group by id_user


Message édité par polo021 le 21-12-2006 à 16:26:34
n°1494947
mrbebert
Posté le 21-12-2006 à 17:14:11  profilanswer
 

SELECT COUNT(*) AS nb_cochons FROM Cochon
SELECT COUNT(*) AS nb_users FROM User
Et on fait la division entre les 2 dans le script appellant
 
(2 requêtes, certes, mais super optimisées :o )

n°1494949
MagicBuzz
Posté le 21-12-2006 à 17:21:25  profilanswer
 

à vue de nez, c'est la première qui est la plus rapide

n°1494970
anapajari
s/travail/glanding on hfr/gs;
Posté le 21-12-2006 à 18:36:49  profilanswer
 

je suis fatigué où la 1ere requête va toujours remonter 1 ???

n°1494975
nero27
Posté le 21-12-2006 à 18:56:27  profilanswer
 

flo850 a écrit :

ca devait marcher :  
 
SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user  FROM cochon


Celle-ci est nickel, merci :jap:

n°1494977
MagicBuzz
Posté le 21-12-2006 à 18:57:35  profilanswer
 

anapajari a écrit :

je suis fatigué où la 1ere requête va toujours remonter 1 ???


 
non, count(distinct champ) retourne le nombre d'occurences différentes du champ.
donc on a bien count(distinct iduser) <= count(idcochon) dans la table cochon

Message cité 1 fois
Message édité par MagicBuzz le 21-12-2006 à 18:57:53
n°1494986
mrbebert
Posté le 21-12-2006 à 19:07:51  profilanswer
 

On notera tout de même que cette requête calcule le nombre moyens de cochons parmi les users qui ont au moins un cochon. S'il y en a qui n'en ont pas, ils ne seront pas pris en compte dans le calcul.
(il était fondamental de le signaler :o )

n°1495012
polo021
Posté le 21-12-2006 à 20:17:21  profilanswer
 

effectivement apres verification sur db2 (mais sans données de masse), la query de flo est + rapide que la mienne

Message cité 1 fois
Message édité par polo021 le 21-12-2006 à 20:17:44
mood
Publicité
Posté le 21-12-2006 à 20:17:21  profilanswer
 

n°1495060
flo850
moi je
Posté le 21-12-2006 à 21:26:50  profilanswer
 

anapajari a écrit :

je suis fatigué où la 1ere requête va toujours remonter 1 ???


quand même , je  ne mets pas que des conneries  [:twixy]  

mrbebert a écrit :

On notera tout de même que cette requête calcule le nombre moyens de cochons parmi les users qui ont au moins un cochon. S'il y en a qui n'en ont pas, ils ne seront pas pris en compte dans le calcul.
(il était fondamental de le signaler :o )


 c'est un point important, je suis parti de l'a priori ( pas forcement vrai ) qu'il y avait au moins un cochon par user

n°1495120
nero27
Posté le 21-12-2006 à 23:05:39  profilanswer
 

En effet, le fait qu'il y ait au moins un cochon par user était ce qu'il me fallait ;)

n°1495202
anapajari
s/travail/glanding on hfr/gs;
Posté le 22-12-2006 à 10:12:23  profilanswer
 

MagicBuzz a écrit :

non, count(distinct champ) retourne le nombre d'occurences différentes du champ.
donc on a bien count(distinct iduser) <= count(idcochon) dans la table cochon


ça je suis d'accord que tu as bien une infériorité, mais l'opération sur deux fonctions d'aggrégation ça m'apparait toujours moyen ... Mais bon j'ai testé sous MySQL ça marche.
Par contre

polo021 a écrit :

effectivement apres verification sur db2 (mais sans données de masse), la query de flo est + rapide que la mienne


Tu peux me montrer les query et les résultats que tu as fait? Nan parce que moi sous db2 ça me donne:

[db2inst1@prod db2inst1]$ db2 "select count(fin_id), count(distinct fin_iddos) from finan"
 
1           2
----------- -----------
    5307596     2894135
 
  1 record(s) selected.
 
[db2inst1@prod db2inst1]$ db2 "select count(fin_id)/ count(distinct fin_iddos) from finan"
 
1
-----------
          1
 
  1 record(s) selected.


Normal que ça soit plus rapide :o :o  ( c'est un db2 V8.1FP8)

n°1495231
MagicBuzz
Posté le 22-12-2006 à 11:11:32  profilanswer
 

ça c'est parceque DB2 est crétin et que le COUNT() retourne un INT au lieu d'un NUMERIC : là tu fais une division entre deux entiers. donc le count retourne un entier. 2 > 5 307 596 / 2 894 135 > 1 donc en entier ça fait 1.
avec un NUMERIC (donc nombre décimal) ça doit marcher.
 
il suffit donc caster les valeur de retour en numeric ou float au moment de la division pour retrouver le bon résultat.

Message cité 1 fois
Message édité par MagicBuzz le 22-12-2006 à 11:14:07
n°1495233
MagicBuzz
Posté le 22-12-2006 à 11:13:30  profilanswer
 

Avec Oracle :
 


COUNT(*) COUNT(DISTINCT NUMEVE) COUNT(*)/COUNT(DISTINCT NUMEVE)
753435   230273                 3.27192072018865


Message édité par MagicBuzz le 22-12-2006 à 11:15:13
n°1495236
MagicBuzz
Posté le 22-12-2006 à 11:16:25  profilanswer
 

mrbebert a écrit :

On notera tout de même que cette requête calcule le nombre moyens de cochons parmi les users qui ont au moins un cochon.


en effet. il reste à savoir si les utilisateurs sans kochons sont à prendre en considération ou non.

n°1495237
anapajari
s/travail/glanding on hfr/gs;
Posté le 22-12-2006 à 11:17:20  profilanswer
 

MagicBuzz a écrit :

ça c'est parceque DB2 est crétin et que le COUNT() retourne un INT au lieu d'un NUMERIC : là tu fais une division entre deux entiers. donc le count retourne un entier. 2 > 5 307 596 / 2 894 135 > 1 donc en entier ça fait 1.
avec un NUMERIC (donc nombre décimal) ça doit marcher.
 
il suffit donc caster les valeur de retour en numeric ou float au moment de la division pour retrouver le bon résultat.


 :jap: yes master! Totally true!

n°1495274
polo021
Posté le 22-12-2006 à 11:51:46  profilanswer
 

anapajari a écrit :

ça je suis d'accord que tu as bien une infériorité, mais l'opération sur deux fonctions d'aggrégation ça m'apparait toujours moyen ... Mais bon j'ai testé sous MySQL ça marche.
Par contre
 
Tu peux me montrer les query et les résultats que tu as fait? Nan parce que moi sous db2 ça me donne:

[db2inst1@prod db2inst1]$ db2 "select count(fin_id), count(distinct fin_iddos) from finan"
 
1           2
----------- -----------
    5307596     2894135
 
  1 record(s) selected.
 
[db2inst1@prod db2inst1]$ db2 "select count(fin_id)/ count(distinct fin_iddos) from finan"
 
1
-----------
          1
 
  1 record(s) selected.


Normal que ça soit plus rapide :o :o  ( c'est un db2 V8.1FP8)


db2 => SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user  FROM
 cochons
 
NB_COCHON_PAR_USER
------------------
                 4
 
  1 record(s) selected.


et

db2 => select avg(cnt) from (select count(*) cnt from cochons group by iduser) a
s v1
 
1
-----------
          4
 
  1 record(s) selected.

n°1495301
anapajari
s/travail/glanding on hfr/gs;
Posté le 22-12-2006 à 12:22:13  profilanswer
 

oui s'bon j'ai compris ou était ma boulette hein :o
Le test ramenait 1.96 et comme MagicBuzz l'a fort justement souligné, c'était casté en int donc ça affichait 1.
Du coup pour que ça affiche la vrai moyenne et pas la moyenne arrondi

SELECT CAST(COUNT(idCochon) as DECIMAL(14,4))/CAST(COUNT(DISTINCT idUser) as DECIMAL(14,4)) as nb_cochon_par_user  FROM
 cochons


edit:
Si tu fais un show optimized query des deux il te sort quoi?


Message édité par anapajari le 22-12-2006 à 12:23:11
n°1495315
polo021
Posté le 22-12-2006 à 12:54:04  profilanswer
 

je ne dois faire aucun casting pour que ca m'affiche ca correctement.
 
EDIT :  
show optinized de SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user  FROM cochons donne  

SELECT (Q3.$C0 / Q3.$C1) AS "NB_COCHON_PAR_USER"  
FROM  
(SELECT COUNT(* ), COUNT(DISTINCT Q2.$C0)  
FROM  
(SELECT Q1.IDUSER  
FROM ARNAUD1.COCHONS AS Q1) AS Q2) AS Q3


cout : 320489 instructions CPU
 
et show optinized de select avg(cnt) from (select count(*) cnt from cochons group by iduser) as v1 donne  

SELECT (Q5.$C0 / Q5.$C1)  
FROM  
(SELECT SUM(Q4.$C0), COUNT(* )  
FROM  
(SELECT Q3.$C0  
FROM  
(SELECT COUNT(* )  
FROM  
(SELECT Q1.IDUSER  
FROM ARNAUD1.COCHONS AS Q1) AS Q2  
GROUP BY Q2.$C0) AS Q3) AS Q4) AS Q5


cout : 323834 instructions CPU


Message édité par polo021 le 22-12-2006 à 13:06:46
n°1495337
flo850
moi je
Posté le 22-12-2006 à 13:54:41  profilanswer
 

donc c'est kif kif en fait ( 1% d'ecart )

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Moyenne un peu compliquée

 

Sujets relatifs
[résolu] Besoin d'aide pour écrire une requête SQL compliquéeCalcule de somme saisie et moyenne.
Structure de requete compliquée HELP PLEASEaide calcule de moyenne
[C] Moyenne d'entiers -> résultat à virgulecalculer une moyenne en enlevant avant deux données...
[RESOLU][Javascript] Mise en page compliquée :)prob Variable et fonction moyenne
Access, requète un peu compliquée...une requete assez compliquée
Plus de sujets relatifs à : Moyenne un peu compliquée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR