sql >> Base de Datos >  >> RDS >> Mysql

Usando MEDIAN junto con las funciones MAX, MIN y AVG en MySQL

Puede calcular la mediana con GROUP BY en MySQL aunque no haya una función mediana incorporada.

Considere la tabla:

Acrington   200.00
Acrington   200.00
Acrington   300.00
Acrington   400.00
Bulingdon   200.00
Bulingdon   300.00
Bulingdon   400.00
Bulingdon   500.00
Cardington  100.00
Cardington  149.00
Cardington  151.00
Cardington  300.00
Cardington  300.00

Para cada fila puedes contar el número de elementos similares que son menores. También puedes contar cuántos valores son menores o iguales:

name        v       <   <=
Acrington   200.00  0   2
Acrington   200.00  0   2
Acrington   300.00  2   3
Acrington   400.00  3   4
Bulingdon   200.00  0   1
Bulingdon   300.00  1   2
Bulingdon   400.00  2   3
Bulingdon   500.00  3   4
Cardington  100.00  0   1
Cardington  149.00  1   2
Cardington  151.00  2   3
Cardington  300.00  3   5
Cardington  300.00  3   5

Con consulta

SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
             , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
  FROM sale o

El valor de la mediana se producirá cuando el recuento menor o igual sea la mitad del número de elementos

  • Acrington tiene 4 artículos. La mitad de esto es 2 que está en el rango 0..2 (correspondiente a 200.00) y también en el rango 2..3 (correspondiente a 300.00)

  • Bullingdon también tiene 4 artículos. 2 está en el rango 1..2 (valor 300.00) y 2..3 (valor 400.00)

  • Cardington tiene 5 artículos. El valor 2,5 está entre 2 y 3 que corresponde a Cardington 151.

El valor de la mediana es la media de los valores mínimo y máximo devueltos por:

SELECT cs.name,v
   FROM
   (SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
                 , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
      FROM sale o) cs JOIN
   (SELECT name,COUNT(1)*.5 as cn
      FROM sale
      GROUP BY name) cc ON cs.name=cc.name
 WHERE cn between ls and lse

Lo que da:

Acrington   200.00
Acrington   200.00
Acrington   300.00
Bulingdon   300.00
Bulingdon   400.00
Cardington  151.00

Finalmente podemos obtener la mediana:

SELECT name,(MAX(v)+MIN(v))/2 FROM
(SELECT cs.name,v
   FROM
   (SELECT name,v, (SELECT COUNT(1) FROM sale WHERE v<o.v AND name=o.name) as ls
                 , (SELECT COUNT(1) FROM sale WHERE v<=o.v AND name=o.name) as lse
      FROM sale o) cs JOIN
   (SELECT name,COUNT(1)*.5 as cn
      FROM sale
     GROUP BY name) cc ON cs.name=cc.name
 WHERE cn between ls and lse
 ) AS medians
GROUP BY name

Dando

Acrington   250.000000
Bulingdon   350.000000
Cardington  151.000000