Shlomi と Zishan (Shlomi のコードを使用) からの応答は、私の大きなテーブルで結果を調べて発見したように、間違いなく正確な結果をもたらしません。他の場所で回答されているように、単一の MySQL クエリでパーセンタイル ランクを計算することは明らかに不可能です:
SQL ランク パーセンタイル
ユーザー定義変数を使用する Shlomi Noach アプローチは、最初は、ランキングの上位 2 パーセントではうまく機能しているように見えますが、テーブル内の下位の行ではすぐに機能が低下します。私が行ったように、自分でデータ結果を見てください。
単一の SQL ステートメント内でユーザー定義変数を使用する Shlomi のアプローチがうまくいかない理由について、Roland Bouman によるこのブログ投稿を参照してください。
http://rpbouman.blogspot.com/2009/09/mysql-another-ranking-trick.html
それで、私はこの目的のために Bouman のコードを適応させました。ここに私の解決策があります。これは、必然的に PHP と MySQL を組み合わせたものです。
ステップ 1) 次の 2 つのクエリを送信して、各行の絶対ランクを計算して保存します。
SET @@group_concat_max_len := @@max_allowed_packet;
UPDATE mytable INNER JOIN (SELECT ID, FIND_IN_SET(
score,
(SELECT GROUP_CONCAT(
DISTINCT score
ORDER BY score DESC
)
FROM mytable)
) AS rank
FROM mytable) AS a
ON mytable.ID=a.ID
SET mytable.rank = rank;
ステップ 2: 行の総数を取得します (そして結果を PHP 変数 $total に格納します)
SELECT COUNT(ID) FROM mytable
ステップ 3: PHP ループを使用してテーブルを反復処理し、各行の絶対ランクを使用して行のパーセンタイル ランクを計算します。
3a) ループスルー:
SELECT ID, rank FROM mytable
これらの行の値を PHP で $ID および $rank として保存するとき
3b) 各行の実行について:
$sql = 'UPDATE mytable INNER JOIN (
SELECT (100*COUNT(ID)/'.$total.') percentile
FROM mytable
WHERE rank >= '.$rank.'
) a
ON mytable.ID = a.ID
WHERE mytable.ID='.$ID.'
SET mytable.percentile = a.percentile';
おそらく最も効率的なプロセスではありませんが、間違いなく正確です。私の場合、「スコア」値はあまり頻繁に更新されないため、上記のスクリプトを cron バッチ操作として実行して、パーセンタイル ランクを最新の状態に保ちます。