2011-01-11 6 views
4

学校区には38の小学校があります。子供たちはテストを受けた。学校の平均は広く分散していますが、各学校のJUST THE TOP 10の平均を比較したいと思います。各学校からトップ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 - 宿題のようですが、これはまあまあです。

答えて

8

this techniqueを使用します。

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 
+0

+1。変数名だけが私の解決策と異なっています:) – Ronnis

+0

うわー!コードがどのくらいコンパクトであるかを見て、私の目は迷っていました。数百行から13まで。はい、バターのように機能します。どうもありがとうございました!! – dave

+0

@Martin .. so awesome ... – Ben

関連する問題