¿Cómo encuentro el valor medio de una columna en MySQL?

10

Solo puedo imaginar hacer esto con dos consultas de base de datos. El primero encuentra el número de filas en la base de datos, y el segundo selecciona con un ORDER BYen la columna que me interesa y LIMIT X, 1donde X es la mitad del número de filas.

¿Hay una manera simple de hacer esto con una sola consulta?

En este momento estoy usando promedios en mis cálculos, pero creo que la media sería mejor; no hay límite superior a los valores y están limitados desde abajo por 0.


EDITAR: sí, quise decir 'mediana' pero estaba teniendo un error cerebral y busqué 'mean'. Ahora he encontrado la respuesta en stackoverflow

JIStone
fuente
Después de leer el metapor un momento, parece que hay una división en cuanto al clima, esta pregunta debería estar aquí o en SO. Reconozco que esto podría no ser una consulta de nivel ninja , pero me dejó perplejo y no hay DBA en la empresa para la que trabajo (6 personas en total).
JIStone

Respuestas:

6

Hay un poco de debate aquí en el cálculo de los valores medios de una tabla de MySQL. Solo busca en la página 'mediana'.

Como comentario aparte, me parece negligente que no haya una función incorporada para hacer esto. La mediana suele ser más descriptiva de la tendencia central que la media. Access / VBA tiene el mismo agujero en su lista de funciones.

Snubian
fuente
Estoy de acuerdo. Cuando se trabaja en una consulta grande, las líneas adicionales solo hacen que todo sea más engorroso y difícil de depurar / mantener.
JIStone 05 de
2

No he visto una solución en ningún lugar que logre obtener la mediana en una sola consulta. No me importan las tablas temporales, pero si no son necesarias, ¡genial! Esto es lo que se me ocurrió:

SELECT AVG(profit) median, nofitems FROM(
  SELECT x.profit, SUM(SIGN(1.0-SIGN(y.profit-x.profit))) diff, count(*) nofitems, floor(count(*)+1/2)
  FROM brand_prof x, brand_prof y
  GROUP BY x.profit
  HAVING SUM(SIGN(1.0-SIGN(y.profit-x.profit))) = floor((COUNT(*)+1)/2)
      OR SUM(SIGN(1.0-SIGN(y.profit-x.profit))) = ceiling((COUNT(*)+1)/2)
) x;

Probé esto para un conjunto uniforme, y obtuve la respuesta correcta. brand_prof son solo dos columnas: brand_name y profit, un valor decimal. Si se tratara de valores enteros, es posible que tenga que emitir "techo ((CAST COUNT (*) AS DECIMAL) ..." Más de lo que he probado. La idea genial de usar un producto cartesiano y relacionar la suma de los signos era no mío. Me he olvidado del autor, lamentablemente.

Jeff Humphreys
fuente