Anda dapat menghitung median dengan GROUP BY di MySQL meskipun tidak ada fungsi median bawaan.
Perhatikan tabelnya:
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
Untuk setiap baris Anda dapat menghitung jumlah item serupa yang lebih sedikit. Anda juga dapat menghitung berapa banyak nilai yang kurang dari atau sama dengan:
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
Dengan kueri
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
Nilai median akan muncul ketika jumlah kurang dari atau sama dengan setengah dari jumlah item
-
Acrington memiliki 4 item. Setengah dari ini adalah 2 yang berada di kisaran 0..2 (sesuai dengan 200,00) dan juga dalam kisaran 2.3 (sesuai dengan 300,00)
-
Bullingdon juga memiliki 4 item. 2 berada pada rentang 1..2 (nilai 300,00) dan 2.3 (nilai 400,00)
-
Kardington memiliki 5 item. Nilai 2.5 adalah antara 2 dan 3 yang sesuai dengan Cardington 151.
Nilai median adalah rata-rata dari nilai min dan max yang dikembalikan oleh:
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
Yang memberikan:
Acrington 200.00
Acrington 200.00
Acrington 300.00
Bulingdon 300.00
Bulingdon 400.00
Cardington 151.00
Akhirnya kita bisa mendapatkan 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
Memberi
Acrington 250.000000
Bulingdon 350.000000
Cardington 151.000000