Je kunt de mediaan berekenen met GROUP BY in MySQL, ook al is er geen mediaanfunctie ingebouwd.
Beschouw de 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
Voor elke rij kun je het aantal vergelijkbare items tellen dat minder is. Je kunt ook tellen hoeveel waarden kleiner of gelijk zijn aan:
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
Met vraag
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
De mediaanwaarde treedt op wanneer het aantal minder dan of gelijk aan de helft van het aantal items is
-
Acrington heeft 4 artikelen. De helft hiervan is 2 in het bereik 0..2 (overeenkomend met 200.00) en ook in het bereik 2..3 (overeenkomend met 300.00)
-
Bullingdon heeft ook 4 items. 2 ligt in het bereik 1..2 (waarde 300.00) en 2..3 (waarde 400.00)
-
Cardington heeft 5 artikelen. De waarde 2,5 ligt tussen 2 en 3 wat overeenkomt met Cardington 151.
De mediaanwaarde is het gemiddelde van de minimum- en maximumwaarden die worden geretourneerd door:
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
Wat geeft:
Acrington 200.00
Acrington 200.00
Acrington 300.00
Bulingdon 300.00
Bulingdon 400.00
Cardington 151.00
Eindelijk kunnen we de mediaan krijgen:
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
Geven
Acrington 250.000000
Bulingdon 350.000000
Cardington 151.000000