Такива неща са голяма болка в MySQL. Може да е разумно да използвате безплатното издание на Oracle Express или postgreSQL, ако възнамерявате да извършвате тази статистическа работа по класиране. Всички те имат MEDIAN(value)
агрегатни функции, които са или вградени, или налични като разширения. Ето малко sqlfiddle, което демонстрира това. http://sqlfiddle.com/#!4/53de8/6/0
Но вие не попитахте за това.
В MySQL вашият основен проблем е обхватът на променливи като @rownum. Имате и проблем със завъртането:това означава, че трябва да превърнете редовете на вашата заявка в колони.
Нека първо се заемем с проблема с въртенето. Това, което ще направите, е да създадете обединение от няколко големи дебели заявки. Например:
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
И така, ето вашите резултати в таблица с двойки етикет/стойност. Можете да завъртите тази таблица така, за да получите един ред със стойност във всяка колона.
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
Ето как завъртате редове (от заявката UNION в този случай) към колони. Ето един урок по темата. http://www.artfulsoftware.com/infotree/qrytip.php?id =523
Сега трябва да се заемем с подзаявките за средно изчисление. Кодът във вашия въпрос изглежда доста добре. Нямам вашите данни, така че ми е трудно да ги оценя.
Но трябва да избягвате повторното използване на променливата @rownum. Наречете го @rownum1 в една от вашите заявки, @rownum2 в следващата и т.н. Ето една скъпа sql цигулка, която прави само едно от тези. http://sqlfiddle.com/#!2/2f770/1/0
Сега нека го изградим малко, като направим две различни медиани. Ето цигулката http://sqlfiddle.com/#!2/2f770/2/ 0
и ето заявката UNION. Забележка втората половина на заявката за обединение използва @rownum2
вместо @rownum
.
И накрая, ето пълната заявка със завъртането. 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
Това са само две медиани. Имате нужда от пет. Мисля, че е лесно да се докаже, че това изчисление на медианата е абсурдно трудно да се направи в MySQL в една заявка.