2010-10-08 26 views
10

J'utilise actuellement la requête suivante pour obtenir quelques chiffres:Calcul de la moyenne pondérée dans MySQL?

SELECT gid, count(gid), (SELECT cou FROM size WHERE gid = infor.gid)  
FROM infor 
WHERE id==4325 
GROUP BY gid; 

La sortie Je reçois à mon stade actuel est le suivant:

+----------+-----------------+---------------------------------------------------------------+ 
| gid  | count(gid)  | (SELECT gid FROM size WHERE gid=infor.gid)     | 
+----------+-----------------+---------------------------------------------------------------+ 
|  19 |    1 |               19 | 
|  27 |    4 |               27 | 
|  556 |    1 |               556 | 
+----------+-----------------+---------------------------------------------------------------+ 

Je suis en train de calculer le-à-dire moyen pondéré

(1 * 19 + 4 * 27 + 1 * 556)/(19 + 27 + 556)

Existe-t-il un moyen de le faire en utilisant une seule requête?

Répondre

13

Utilisation:

SELECT SUM(x.num * x.gid)/SUM(x.cou) 
    FROM (SELECT i.gid, 
       COUNT(i.gid) AS num, 
       s.cou 
      FROM infor i 
    LEFT JOIN SIZE s ON s.gid = i.gid 
     WHERE i.id = 4325 
     GROUP BY i.gid) x 
+0

Génial ... Merci beaucoup pour cela. J'étais sur le point d'écrire une boucle imbriquée dans une procédure, mais je suis tombé sur un article qui disait "Si vous avez besoin d'une boucle imbriquée, alors vous n'avez pas regardé JOIN" :) – Legend

+0

@legend: Le conseil est correct, mais JOINs aussi risque de gonfler les dossiers s'il y a plus d'un enfant associé au parent. Si vous voulez des lignes distinctes du parent, il est préférable d'utiliser une sous-requête (EXISTS serait ma recommandation). –

+0

Je vois. Dans mon cas, il y a exactement un élément mais je garderai votre conseil en tête. – Legend

1

Vous pouvez placer votre requête d'origine en tant que sous-requête et SUM les enregistrements. Je ne pouvais pas tester ce que je n'ai pas l'ensemble de données que vous faites, mais il devrait fonctionner en théorie;)

SELECT SUM(gid)/SUM(weights) AS calculated_average FROM (
    SELECT gid, (COUNT(gid) * gid) AS weights 
    FROM infor 
    WHERE id = 4325 
    GROUP BY gid); 
+0

+1 pour cette approche. Je vous remercie. Juste curieux de savoir lequel est le plus efficace. Va courir à 'EXPLAIN' et voir. – Legend

+0

@Legend, pas de problème. Vous pouvez en fait avoir besoin du 'JOIN ', mais de l'OP, je n'ai pas vu sa nécessité. –