Du kan beräkna medianen med GROUP BY i MySQL även om det inte finns någon medianfunktion inbyggd.
Tänk på tabellen:
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
För varje rad kan du räkna antalet liknande föremål som är färre. Du kan också räkna hur många värden som är mindre än eller lika med:
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
Med fråga
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
Medianvärdet uppstår när antalet mindre än-eller-lika är hälften av antalet objekt
-
Acrington har 4 artiklar. Hälften av detta är 2 som ligger i intervallet 0..2 (motsvarande 200.00) och även i intervallet 2..3 (motsvarande 300.00)
-
Bullingdon har även 4 artiklar. 2 är i intervallet 1..2 (värde 300.00) och 2..3 (värde 400.00)
-
Cardington har 5 artiklar. Värdet 2,5 är mellan 2 och 3 vilket motsvarar Cardington 151.
Medianvärdet är medelvärdet av min- och maxvärdena som returneras av:
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
Vilket ger:
Acrington 200.00
Acrington 200.00
Acrington 300.00
Bulingdon 300.00
Bulingdon 400.00
Cardington 151.00
Äntligen kan vi få medianen:
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
Ge
Acrington 250.000000
Bulingdon 350.000000
Cardington 151.000000