Moyenne un peu compliquée - SQL/NoSQL - Programmation
Marsh Posté le 21-12-2006 à 15:41:14
ca devait marcher :
SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user FROM cochon
Marsh Posté le 21-12-2006 à 16:25:25
select avg(cnt) from select count(*) as cnt from cochon group by id_user
Marsh Posté le 21-12-2006 à 17:14:11
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 )
Marsh Posté le 21-12-2006 à 18:36:49
ReplyMarsh Posté le 21-12-2006 à 18:56:27
flo850 a écrit : ca devait marcher : |
Celle-ci est nickel, merci
Marsh Posté le 21-12-2006 à 18:57:35
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
Marsh Posté le 21-12-2006 à 19:07:51
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 )
Marsh Posté le 21-12-2006 à 20:17:21
effectivement apres verification sur db2 (mais sans données de masse), la query de flo est + rapide que la mienne
Marsh Posté le 21-12-2006 à 21:26:50
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
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. |
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
Marsh Posté le 21-12-2006 à 23:05:39
En effet, le fait qu'il y ait au moins un cochon par user était ce qu'il me fallait
Marsh Posté le 22-12-2006 à 10:12:23
MagicBuzz a écrit : non, count(distinct champ) retourne le nombre d'occurences différentes du champ. |
ç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" |
Normal que ça soit plus rapide ( c'est un db2 V8.1FP8)
Marsh Posté le 22-12-2006 à 11:11:32
ç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.
Marsh Posté le 22-12-2006 à 11:13:30
Avec Oracle :
|
Marsh Posté le 22-12-2006 à 11:16:25
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.
Marsh Posté le 22-12-2006 à 11:17:20
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. |
yes master! Totally true!
Marsh Posté le 22-12-2006 à 11:51:46
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.
|
db2 => SELECT COUNT(idCochon)/COUNT(DISTINCT idUser) as nb_cochon_par_user FROM |
et
db2 => select avg(cnt) from (select count(*) cnt from cochons group by iduser) a |
Marsh Posté le 22-12-2006 à 12:22:13
oui s'bon j'ai compris ou était ma boulette hein
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 |
edit:
Si tu fais un show optimized query des deux il te sort quoi?
Marsh Posté le 22-12-2006 à 12:54:04
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" |
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) |
cout : 323834 instructions CPU
Marsh Posté le 21-12-2006 à 15:14:50
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
Message édité par nero27 le 21-12-2006 à 15:15:34