Bagaimana cara menemukan nilai median kolom di MySQL?

10

Saya hanya bisa membayangkan melakukan ini dengan dua permintaan basis data. Yang pertama menemukan jumlah baris dalam database, dan yang kedua memilih dengan ORDER BYpada kolom saya tertarik dan di LIMIT X, 1mana X adalah setengah jumlah baris.

Apakah ada cara sederhana untuk melakukan ini hanya dengan satu permintaan?

Saat ini saya menggunakan rata-rata dalam perhitungan saya, tetapi saya pikir rata-rata akan lebih baik; tidak ada batas atas nilai dan mereka dibatasi dari bawah oleh 0.


EDIT: ya, saya bermaksud mengatakan 'median' tetapi mengalami beberapa kesalahan otak & mencari 'berarti'. Saya sekarang telah menemukan jawabannya di stackoverflow

JIStone
sumber
Setelah membaca metasebentar sepertinya ada pembagian untuk cuaca pertanyaan ini harus di sini atau di SO. Saya menyadari ini mungkin bukan permintaan tingkat ninja , tapi itu membuat saya bingung dan tidak ada DBA di perusahaan tempat saya bekerja (total 6 orang).
JIStone

Jawaban:

6

Ada sedikit diskusi di sini tentang menghitung nilai median dari tabel MySQL. Cukup cari halaman untuk 'median'.

Selain itu, saya terkejut karena tidak ada fungsi bawaan untuk melakukan ini. Median sering lebih deskriptif kecenderungan sentral daripada rata-rata. Access / VBA memiliki lubang yang sama dalam daftar fungsinya.

Snubian
sumber
Saya setuju. Ketika dikerjakan ke dalam kueri besar, baris tambahan hanya membuat semuanya lebih rumit & sulit untuk di-debug / dipelihara.
JIStone
2

Saya belum melihat solusi di mana pun yang berhasil mendapatkan median dalam satu permintaan. Saya tidak keberatan tabel temp, tetapi jika mereka tidak perlu, bagus! Inilah yang saya pikirkan:

SELECT AVG(profit) median, nofitems FROM(
  SELECT x.profit, SUM(SIGN(1.0-SIGN(y.profit-x.profit))) diff, count(*) nofitems, floor(count(*)+1/2)
  FROM brand_prof x, brand_prof y
  GROUP BY x.profit
  HAVING SUM(SIGN(1.0-SIGN(y.profit-x.profit))) = floor((COUNT(*)+1)/2)
      OR SUM(SIGN(1.0-SIGN(y.profit-x.profit))) = ceiling((COUNT(*)+1)/2)
) x;

Saya menguji ini untuk set genap, dan mendapat jawaban yang tepat. brand_prof hanya dua kolom: brand_name, dan laba, nilai desimal. Jika ini adalah nilai integer, Anda mungkin harus menggunakan "ceiling ((CAST COUNT (*) AS DECIMAL) ..." Lebih dari yang saya uji. Gagasan keren untuk menggunakan produk kartesius dan menghubungkan jumlah tanda itu bukan milikku, aku lupa penulisnya, sayangnya.

Jeff Humphreys
sumber