2016-03-19 8 views
1

私は学生のための歴史試験の合計得点を保持するこのようなテーブルがあります。Mysql、割合でユーザーをランキング

+----+---------------+-------+---------+- 
| id | name   | history | rank | 
+----+---------------+-------+---------+- 
| 1 | yngiid  | 97 |  | 
| 2 | viyrp   | 217 |  | 
| 3 | pae   | 599 |  | 
| 4 | spohl   | 284 |  | 
| 5 | shl   | 295 |  | 
| 6 | okeer   | 73 |  | 
| 7 | jmaany  | 657 |  | 
| 8 | hxt   | 80 |  | 
| 9 | yanier  | 599 |  | 
+----+---------------+-------+----------+- 

あなたが見ることができる履歴フィールドには、学生の合計得点が含まれています。さて、私は学生の得点をランク付けしたいのですが、ポイントが高いほどランクは低くなりますが、パーセンテージを使用するだけです。つまり、ユーザーは1から100までのランク付けが可能で、基本的にはstackoverflowのプロファイルページにあるようになります。top 1%

私はこれを試しました。

SELECT NAME, HISTORY, ROUND(history/100) AS percentage FROM test ORDER BY percentage DESC 

私はこれを取得できました。 TOP 1%または類似した何かを言うように、最低の割合を取得する必要があり、最高HISTORYポイントで100%とユーザ - (1)の割合は、1からでなければなりませんので

name HISTORY percentage 
------ ------- ------------ 
jmaany  657    7 
yanier  599    6 
pae   599    6 
shl   295    3 
spohl  284    3 
viyrp  217    2 
yngiid  97    1 
yngiid  97    1 
okeer  73    1 
yngiid  97    1 
hxt   80    1 
yngiid  97    1 

上記は、間違っています。

ここでは、役立つ場合のサンプルテーブルダンプを示します。 stackoverflowのは、それが言うプロフィールページ、上の持っているものと基本的に同様

create table `test` (
    `id` int (11), 
    `name` varchar (765), 
    `history` int (11), 
    `rank` int (11) 
); 

insert into `test` (`id`, `name`, `history`, `rank`) values 
('1','yngiid','97',NULL), 
('2','viyrp','217',NULL), 
('3','pae','599',NULL), 
('4','spohl','284',NULL), 
('5','shl','295',NULL), 
('6','okeer','73',NULL), 
('7','jmaany','657',NULL), 
('8','hxt','80',NULL), 
('9','yanier','599',NULL); 
+1

?参考値が必要です。あなたが提供したデータの参照値は2つだけです:すべての履歴ポイントの合計、または他の学生と比較したランキングの位置です。より明示的にする必要があります。あなたが望む最終データを表示 –

+0

また、私はこれの背後に論理が表示されません:ポイントが高いほど、ランク(それは論理的です)、なぜ最もポイントを持つ人々が最も低い割合を持っていますか???参考値が –

+0

@ThomasGであることを明確に説明しない限り、それは意味をなさない。わからない。数学は私のためのパズルですが、あなたは私が必要とするものを理解しています。最高得点者を獲得することはできません。 – ANW

答えて

1

...上位1%

トップ1%は、などのランクが書くのは簡単に終了されて表示さstackoverflowのロジック。実際には、ユーザーはのうち1%のうちです。まずすべてのユーザーに対して、評価(history)以上のユーザー数を判断する必要があります。次に、簡単な式numberOfUsersHavingGreaterOrEqualRating/numberofTotalUsers * 100を適用します。あなたのパーセンテージが計算されるべきでないものに

SET @total= (SELECT COUNT(*) FROM stud); 
select s1.*, concat('TOP ', floor(nge/@total * 100), '%') as percent 
from stud s1 
join (select s1.id, count(s2.id) as nge 
    from stud s1 
    join stud s2 
    on s1.history <= s2.history 
    group by s1.id) as s2 
on s1.id = s2.id 
order by history desc 

Play with it

+0

Ok、それをテストします。リフィルする時間。今のところ一つのことだけに興味があり、なぜすべてのデータが同じ数の間隔であるのでしょうか。 11、22、33、44 ..あなたはそれが正しいと確信していますか? – ANW

+0

@ANW、はい。ユーザー数は9人であるため、最初のユーザーであれば、全ユーザーのうち最初の1/9人、またはすべてのユーザーの最初の「11%」になります。 –

+0

私はちょうど今試しました、私はラップトップが物事を取り終えるのを待たなければなりませんでした。とにかく私に迷惑をかける面白い問題があります。私は4Kレコード以上あり、あなたのスクリプトは 'TOP 0%'から始まり 'TOP 100%'で終わることを除いて動作します。だから、 '0%'ちょっと意味がないので、 '' floor(nge/@total * 100 + 1) 'の中に' + 1'を追加して、あなたが推測したように動作しましたが、 。さて、 '100%'は '101%'に変更されました。この小さな問題を解決する方法はありますか? – ANW