Możesz obliczyć medianę za pomocą GROUP BY w MySQL, nawet jeśli nie ma wbudowanej funkcji mediany.
Rozważ tabelę:
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
Dla każdego rzędu możesz policzyć liczbę podobnych pozycji, których jest mniej. Możesz także policzyć, ile wartości jest mniejszych lub równych:
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
Z zapytaniem
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
Mediana pojawi się, gdy liczba mniejsza lub równa będzie o połowę mniejsza niż liczba elementów
-
Acrington ma 4 przedmioty. Połowa z tego to 2, czyli w przedziale 0..2 (co odpowiada 200,00), a także w przedziale 2..3 (co odpowiada 300,00)
-
Bullingdon posiada również 4 pozycje. 2 należy do zakresu 1..2 (wartość 300,00) i 2..3 (wartość 400,00)
-
Cardington ma 5 sztuk. Wartość 2,5 wynosi od 2 do 3, co odpowiada Cardington 151.
Mediana jest średnią wartości minimalnych i maksymalnych zwracanych przez:
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
Co daje:
Acrington 200.00
Acrington 200.00
Acrington 300.00
Bulingdon 300.00
Bulingdon 400.00
Cardington 151.00
Wreszcie możemy uzyskać medianę:
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
Dawanie
Acrington 250.000000
Bulingdon 350.000000
Cardington 151.000000