sql >> Database >  >> RDS >> Mysql

Bereken medianen voor meerdere kolommen in dezelfde tabel in één queryaanroep

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.



  1. Hoe twee kolommen in een MySQL-database bij te werken?

  2. Wat is de meest efficiënte manier om duizenden entiteiten te behouden?

  3. Meerdere PHP WHILE-loops met dezelfde query

  4. Toon string van raise_application_error in Java-programma