Hal semacam ini adalah rasa sakit yang besar di leher di MySQL. Anda mungkin bijaksana untuk menggunakan Oracle Express Edition atau postgreSQL gratis jika Anda akan melakukan tonase pekerjaan peringkat statistik ini. Semuanya memiliki MEDIAN(value)
fungsi agregat yang baik built-in atau tersedia sebagai ekstensi. Inilah sedikit sqlfiddle yang menunjukkannya. http://sqlfiddle.com/#!4/53de8/6/0
Tapi Anda tidak bertanya tentang itu.
Di MySQL, masalah dasar Anda adalah cakupan variabel seperti @rownum. Anda juga memiliki masalah pivot:yaitu, Anda perlu mengubah baris kueri menjadi kolom.
Mari kita atasi masalah pivot terlebih dahulu. Apa yang akan Anda lakukan adalah membuat gabungan dari beberapa kueri besar. Misalnya:
SELECT 'median_wages' AS tag, wages AS value
FROM (big fat query making median wages) A
UNION
SELECT 'median_volunteer_hours' AS tag, hours AS value
FROM (big fat query making median volunteer hours) B
UNION
SELECT 'median_solvent_days' AS tag, days AS value
FROM (big fat query making median solvency days) C
Jadi, inilah hasil Anda dalam tabel pasangan tag/nilai. Anda dapat memutar tabel seperti itu, untuk mendapatkan satu baris dengan nilai di setiap kolom.
SELECT SUM( CASE tag WHEN 'median_wages' THEN value ELSE 0 END
) AS median_wages,
SELECT SUM( CASE tag WHEN 'median_volunteer_hours' THEN value ELSE 0 END
) AS median_volunteer_hours,
SELECT SUM( CASE tag WHEN 'median_solvent_days' THEN value ELSE 0 END
) AS median_solvent_days
FROM (
/* the above gigantic UNION query */
) Q
Begitulah cara Anda memutar baris (dari kueri UNION dalam kasus ini) ke kolom. Berikut adalah tutorial tentang topik tersebut. http://www.artfulsoftware.com/infotree/qrytip.php?id =523
Sekarang kita perlu menangani subquery komputasi median. Kode dalam pertanyaan Anda terlihat cukup bagus. Saya tidak memiliki data Anda sehingga sulit bagi saya untuk mengevaluasinya.
Tetapi Anda harus menghindari penggunaan kembali variabel @rownum. Sebut saja @rownum1 di salah satu kueri Anda, @rownum2 di kueri berikutnya, dan seterusnya. Inilah biola sql mungil yang hanya melakukan salah satunya. http://sqlfiddle.com/#!2/2f770/1/0
Sekarang mari kita membangunnya sedikit, melakukan dua median yang berbeda. Inilah biola http://sqlfiddle.com/#!2/2f770/2/ 0
dan inilah kueri UNION. Pemberitahuan paruh kedua kueri gabungan menggunakan @rownum2
bukannya @rownum
.
Akhirnya, inilah kueri lengkap dengan pivot. http://sqlfiddle.com/#!2/2f770/13/0
SELECT SUM( CASE tag WHEN 'Boston' THEN value ELSE 0 END ) AS Boston,
SUM( CASE tag WHEN 'Bronx' THEN value ELSE 0 END ) AS Bronx
FROM (
SELECT 'Boston' AS tag, pop AS VALUE
FROM (
SELECT @rownum := @rownum +1 AS `row_number` , pop
FROM pops,
(SELECT @rownum :=0)r
WHERE pop >0 AND city = 'Boston'
ORDER BY pop
) AS ordered_rows,
(
SELECT COUNT( * ) AS total_rows
FROM pops
WHERE pop >0 AND city = 'Boston'
) AS rowcount
WHERE ordered_rows.row_number = FLOOR( total_rows /2 ) +1
UNION ALL
SELECT 'Bronx' AS tag, pop AS VALUE
FROM (
SELECT @rownum2 := @rownum2 +1 AS `row_number` , pop
FROM pops,
(SELECT @rownum2 :=0)r
WHERE pop >0 AND city = 'Bronx'
ORDER BY pop
) AS ordered_rows,
(
SELECT COUNT( * ) AS total_rows
FROM pops
WHERE pop >0 AND city = 'Bronx'
) AS rowcount
WHERE ordered_rows.row_number = FLOOR( total_rows /2 ) +1
) D
Ini hanya dua median. Anda membutuhkan lima. Saya pikir mudah untuk membuat kasus bahwa perhitungan median ini sangat sulit dilakukan di MySQL dalam satu permintaan.