SQLでちゃんとしたランキングを作る【1/3】
SQLを使ってランキングを表示させるなんてことをやったことがある人もいるだろう。たとえばメンバー(訪問者という意味でのユーザは2種類あって、登録ユーザをメンバー、非登録ユーザをビジターと呼んでいる)にポイント属性が設定されていて、そのポイントを毎日集計する、そしてその結果、上位から10件取り出せば、ランキングデータが1位までそろう、というものだ。
ちょっと待て!!
それたぶん、インチキ!!
MySQLであれば、
select * from histories order by point desc limit 10と吐けば、pointが高い順に上から10件の結果を得ることはできるが、ただ10件取得するだけで、ランキングとして正しいかどうかは別問題だ。
というのも、同位の場合があるからだ。
ある2人のユーザが同ポイントだった場合、内部ではpointではなくidや登録日などの順で順位が変わってしまうということになる。正直これは不本意だ。
というわけで、いくつかパターンを考えてみる。以下は、3位が二人いる場合を例にとってみた。
順位シーケンシャル | 順位スキップ | |
---|---|---|
10件まで | 1 2 3 3 4 5 6 7 8 9 | 1 2 3 3 5 6 7 8 9 10 |
10位まで | 1 2 3 3 4 5 6 7 8 9 10 | 1 2 3 3 5 6 7 8 9 10 |
これだと、右下の「順位スキップ」+「10位まで」がよさそうだが、実はそうじゃない。
さらに以下は、3位が二人、8位が3人いる場合になる。