2010-04-06 4 views
4

Je ne suis pas sûr si c'est possible ce que j'essaie d'atteindre. Je veux obtenir la moyenne des colonnes moyennées.Moyenne de la moyenne en une ligne

SELECT avg(col1), avg(col2), avg(col3) FROM tbl 

Mon résultat devrait être la moyenne des trois colonnes moyennes, est-ce possible? Quelque chose comme ça

SELECT avg(col1, col2, col3) FROM tbl 

ne fonctionne pas à MySQL 5.1

+0

Soyez conscient que la moyenne des colonnes moyennées peut être complètement différent de la moyenne de toutes les valeurs de la colonne. –

Répondre

4

Avez-vous essayé:

SELECT avg(col1 + col2 + col3)/3.0 FROM tbl 

Vous devez vérifier qu'il y ne sont pas nuls dans cette colonne.

+0

Parfois, il est plus facile de faire une pause et d'y penser, au lieu de forcer quelque chose. Merci à tous pour avoir éclairci mon esprit. – onigunn

5
SELECT (AVG(col1) * COUNT(col1) + 
     AVG(col2) * COUNT(col2) + 
     AVG(col3) * COUNT(col3))/
     (COUNT(col1) + COUNT(col2) + COUNT(col3)) 
FROM tbl 
+1

+1, cela fonctionnera également avec les valeurs nulles, mais ne sera précis que pour un nombre relativement grand de lignes totales par rapport aux lignes avec des valeurs nulles (sinon count (col1) + count (col2) + count (col3) puis 3 * compte (*)); Voici une autre amélioration http://stackoverflow.com/questions/2583742/aviation-de-la-variance-dans-une-heure/2586543#2586543 – Unreason

+0

Sans raison, vous avez raison. J'ai mis à jour ma réponse pour donner une moyenne pondérée. –

1

mathématiques de base:

SELECT AVG(col1 + col2 + col3)/3 FROM tbl 
+0

Ce n'est que "maths de base" si aucune des valeurs n'est nulle. Par exemple, si une ligne est (null, 3, 5) alors "null + 3 + 5" est évalué à null et la ligne est essentiellement ignorée. – redcayuga

3

Juste essayer d'améliorer Anthony et Zendar

SELECT (SUM(col1)+SUM(col2)+SUM(col3))/(COUNT(col1)+COUNT(col2)+COUNT(col3))  
FROM tbl 

Hypothèses:

  • toutes les valeurs ont même signifance (poids)
  • il y a nulls
  • vous voulez toujours bon résultat

problèmes potentiels:

  • pour les entrées entières AVG ne déborde pas où SUM fait, donc une distribution explicite peut être nécessaire

EDIT (grâce à redcayuga): Si l'une des colonnes est NULL pour toutes les lignes ci-dessus renvoie la requête NULL si COALESCE doit être appliqué à SUM

SELECT (COALESCE(SUM(col1),0)+ 
     COALESCE(SUM(col2),0)+ 
     COALESCE(SUM(col3),0))/(COUNT(col1)+COUNT(col2)+COUNT(col3))  
FROM tbl 
+0

Je ne suis pas sûr que toutes les valeurs devraient avoir le même poids. La question initiale semble suggérer le contraire. – redcayuga

+0

Si une colonne contient des valeurs null dans chaque ligne, l'expression sera évaluée à null. Si toutes les lignes sont nulles, une division par zéro sera tentée. – redcayuga

+0

bon point sur tous les NULL dans une colonne, comme pour diviser par zéro - AVG est indéfini dans ce cas, si c'est important de retourner NULL dans ce cas une condition IF peut aider, mais je vais laisser cela comme un exercice pour utilisateur potentiel. :) – Unreason

0

Juste pour le plaisir, voici un peu différente solution qui laisse la manipulation NULL à avg() fonction:

SELECT avg(colValue) from 
    (SELECT col1 as colValue from tbl 
    UNION ALL 
    SELECT col2 as colValue from tbl 
    UNION ALL 
    SELECT col3 as colValue from tbl 
) 

Les valeurs de co1l, col2 et col3 sont placées dans une colonne virtuelle, puis la base de données calcule la moyenne.

Vous n'avez pas à vous soucier des valeurs NULL - base de données et la fonction avg() le fera pour vous.

Remarque: Cela peut être plus lent que d'autres solutions, car il peut provoquer 3 analyses de table complètes pour créer une table virtuelle. Vérifiez le plan d'exécution.

0
SELECT (ISNULL(AVG(col1),0) + ISNULL(AVG(col2),0) + .....) 
    /
     (CASE WHEN AVG(col1) IS NULL THEN 0 ELSE 1 END + CASE WHEN AVG(col2) IS NULL THEN 0 ELSE 1 END +......) 
    FROM tbl 

cela supprimer les valeurs nulles