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