Dit soort dingen is een grote pijn in de nek in MySQL. Het is misschien verstandig om de gratis Oracle Express Edition of postgreSQL te gebruiken als je tonnage van dit statistische rangschikkingswerk gaat doen. Ze hebben allemaal MEDIAN(value)
geaggregeerde functies die ofwel ingebouwd zijn of beschikbaar zijn als extensies. Hier is een kleine sqlfiddle die dat aantoont. http://sqlfiddle.com/#!4/53de8/6/0
Maar daar heb je niet naar gevraagd.
In MySQL is uw basisprobleem het bereik van variabelen zoals @rownum. Je hebt ook een scharnierprobleem:dat wil zeggen, je moet rijen van je zoekopdracht omzetten in kolommen.
Laten we eerst het spilprobleem aanpakken. Wat je gaat doen, is een combinatie maken van verschillende grote vragen. Bijvoorbeeld:
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
Dus hier zijn je resultaten in een tabel met tag / waarde-paren. Je kunt die tabel zo draaien om één rij te krijgen met een waarde in elke 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
Zo draai je rijen omhoog (in dit geval van de UNION-query) naar kolommen. Hier is een tutorial over het onderwerp. http://www.artfulsoftware.com/infotree/qrytip.php?id =523
Nu moeten we de mediaan-computing-subquery's aanpakken. De code in je vraag ziet er goed uit. Ik heb je gegevens niet, dus ik kan ze moeilijk beoordelen.
Maar u moet voorkomen dat u de variabele @rownum opnieuw gebruikt. Noem het @rownum1 in een van uw zoekopdrachten, @rownum2 in de volgende, enzovoort. Hier is een dinky sql-viool die slechts een van deze doet. http://sqlfiddle.com/#!2/2f770/1/0
Laten we het nu een beetje opbouwen, met twee verschillende medianen. Hier is de viool http://sqlfiddle.com/#!2/2f770/2/ 0
en hier is de UNION-query. Opmerking de tweede helft van de samenvoegquery gebruikt @rownum2
in plaats van @rownum
.
Eindelijk, hier is de volledige query met het draaien. 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
Dit zijn slechts twee medianen. Je hebt er vijf nodig. Ik denk dat het gemakkelijk is om te beweren dat deze mediaanberekening absurd moeilijk is om in MySQL in één enkele query uit te voeren.