sql >> Databáze >  >> RDS >> Mysql

Vypočítejte mediány pro více sloupců ve stejné tabulce v jednom volání dotazu

Takové věci jsou v MySQL velkou bolestí v krku. Možná by bylo moudré použít bezplatnou verzi Oracle Express Edition nebo postgreSQL, pokud se chystáte provést toto statistické hodnocení. Všechny mají MEDIAN(value) agregační funkce, které jsou buď vestavěné, nebo dostupné jako rozšíření. Zde je malý sqlfiddle, který to demonstruje. http://sqlfiddle.com/#!4/53de8/6/0

Ale na to jste se neptal.

V MySQL je vaším základním problémem rozsah proměnných jako @rownum. Máte také problém s pivotováním:to znamená, že musíte převést řádky dotazu na sloupce.

Nejprve se vypořádáme s problémem pivotů. Co uděláte, je vytvořit spojení několika velkých tlustých dotazů. Například:

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

Zde jsou tedy vaše výsledky v tabulce párů značka / hodnota. Tuto tabulku můžete takto otočit, abyste získali jeden řádek s hodnotou v každém sloupci.

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

Takto převedete řádky (v tomto případě z dotazu UNION) na sloupce. Zde je návod na dané téma. http://www.artfulsoftware.com/infotree/qrytip.php?id =523

Nyní se musíme vypořádat s poddotazy na výpočet mediánu. Kód ve vaší otázce vypadá docela dobře. Nemám vaše data, takže je pro mě těžké je vyhodnotit.

Musíte se však vyhnout opětovnému použití proměnné @rownum. Nazvěte to @rownum1 v jednom z vašich dotazů, @rownum2 v dalším a tak dále. Zde je malý sql housle, který dělá jen jeden z nich. http://sqlfiddle.com/#!2/2f770/1/0

Nyní to trochu postavíme a uděláme dva různé mediány. Zde jsou housle http://sqlfiddle.com/#!2/2f770/2/ 0 a zde je dotaz UNION. Upozornění druhá polovina sjednocovacího dotazu používá @rownum2 místo @rownum .

Nakonec je zde úplný dotaz s otáčením. 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

To jsou jen dva mediány. Potřebujete pět. Myslím, že je snadné dokázat, že tento výpočet mediánu je v MySQL absurdně obtížné provést v jediném dotazu.



  1. Oracle kontingenční řádky do sloupců

  2. Podmíněné pořadí T-SQL podle

  3. Node.js &MySQL - Chyba:1251 - Klient nepodporuje ověřovací protokol požadovaný serverem; zvažte upgrade klienta MySQL

  4. Odeslání formuláře, mysql a php