Получение среднего из 10 лучших учеников из каждой школы - PullRequest
4 голосов
/ 11 января 2011

У нас есть школьный округ с 38 начальными школами. Дети прошли тест. Средние показатели по школам широко разбросаны, но я хочу сравнить средние значения ТОЛЬКО 10 лучших учеников из каждой школы.

Требование: использовать только временные таблицы.

Я сделал это очень трудоемким, подверженным ошибкам способом, следующим образом.
(sch_code = например, 9043; - schabbrev = например, "Картер"; - totpct_stu = например, 61,3)

DROP TEMPORARY TABLE IF EXISTS avg_top10 ;
CREATE TEMPORARY TABLE avg_top10
   ( sch_code   VARCHAR(4),
     schabbrev  VARCHAR(75),
     totpct_stu DECIMAL(5,1)
   );

INSERT 
  INTO avg_top10
SELECT sch_code
     , schabbrev
     , totpct_stu
  FROM test_table
 WHERE sch_code IN ('5489')
 ORDER
    BY totpct_stu DESC
 LIMIT 10;

-- I do that last query for EVERY school, so the total 
-- length of the code is well in excess of 300 lines.  
-- Then, finally...

SELECT schabbrev, ROUND( AVG( totpct_stu ), 1 ) AS top10
  FROM avg_top10
 GROUP
    BY schabbrev
 ORDER
    BY top10 ;

-- OUTPUT:
-----------------------------------
schabbrev   avg_top10
----------  ---------
Goulding         75.4
Garth            77.7
Sperhead         81.4
Oak_P            83.7
Spring           84.9
-- etc...

Вопрос: Так это работает, но разве нет лучшего способа сделать это?

Спасибо!

PS - Похоже на домашнюю работу, но это, ну ... реально.

1 Ответ

8 голосов
/ 11 января 2011

Используя эту технику .

select sch_code,
       schabbrev,
       ROUND( AVG( totpct_stu ), 1 ) AS top10
from   (select sch_code,
               schabbrev,
               totpct_stu,
               @num := if(@group = sch_code, @num + 1, 1) as row_number,
               @group := sch_code as dummy
        from   test_table
        order by sch_code, totpct_stu desc) as x
where  row_number <= 10
GROUP BY sch_code,
       schabbrev
...