Puoi calcolare la mediana con GROUP BY in MySQL anche se non esiste una funzione mediana incorporata.
Considera la tabella:
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
Per ogni riga puoi contare il numero di elementi simili che sono inferiori. Puoi anche contare quanti valori sono minori o uguali:
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 richiesta
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
Il valore mediano si verificherà quando il conteggio minore o uguale è la metà del numero di elementi
-
Acrington ha 4 articoli. La metà di questo è 2 che è nell'intervallo 0..2 (corrispondente a 200.00) e anche nell'intervallo 2..3 (corrispondente a 300.00)
-
Bullingdon ha anche 4 articoli. 2 è compreso tra 1..2 (valore 300.00) e 2..3 (valore 400.00)
-
Cardington ha 5 articoli. Il valore 2,5 è compreso tra 2 e 3 che corrisponde a Cardington 151.
Il valore mediano è la media dei valori minimo e massimo restituiti da:
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
Che dà:
Acrington 200.00
Acrington 200.00
Acrington 300.00
Bulingdon 300.00
Bulingdon 400.00
Cardington 151.00
Finalmente possiamo ottenere 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
Dare
Acrington 250.000000
Bulingdon 350.000000
Cardington 151.000000