私はMySQLで非常に大きな測定データテーブルを持っており、これらの値ごとにパーセンタイルランクを計算する必要があります。 Oracleにはpercent_rankという機能があるようですが、MySQLの場合はこれと似たものが見つかりません。確かに私はテーブルにデータを入れるために私がとにかく使うPythonで無理矢理強制することができますが、1つのサンプルが200.000回の観測を持つ可能性があるため、非常に非効率的であると思われます。MySQLのパーセンタイルランクの計算
答えて
これは比較的醜い答えです。私はそれを言って罪悪感を感じます。それは、あなたの問題に関してあなたを助けるかもしれない、と言った。
割合を判断する1つの方法は、すべての行を数え、提供した数よりも多い行の数を数えることです。より大きいか小さいかを計算し、必要に応じて逆数を取ることができます。
番号にインデックスを作成します。 合計=選択カウント()。 less_equal =選択カウント()ここで、value> indexed_number;
割合は次のようなものになるだろう:less_equal /合計または(合計 - less_equal)/総
それらの両方は、あなたが作成したインデックスを使用していることを確認してください。そうでない場合は、調整してください。 Explain照会には、右側の列に「使用索引」が必要です。 select count(*)の場合は、InnoDBのインデックスとMyISAMのconstのようなものを使用する必要があります。 MyISAMはいつでもこの値を計算しなくても知ることができます。
%をデータベースに格納する必要がある場合は、上記の設定を使用してパフォーマンスを確認し、2番目のクエリを内部セレクトとして使用して各行の値を計算することができます。最初のクエリの値は定数として設定できます。
これは役に立ちますか?
ヤコブ
私は実際に数週間前にそれを試みました、そして、それは非常に遅かったので、私はpythonでパーセンタイルを計算し、その値をデータベースに入れました。 – lhahne
選択カウント(*)と選択カウント(*)<=あなたの値を使用しようとしましたか?それらの両方が必要な列のみを持つ索引によって処理されていることを確認しましたか?ソリューションがデータ行に全く触れなければならない場合は、1〜2桁遅くなることが予想されます。必要な列以上のインデックスが含まれているか、MySQLのメモリ構成が正しく設定されていない場合は、非常に遅いです。もしそうなら、これは速かったはずです。どのくらいの時間が「信じられないほど遅い」ですか?期待される応答の大きさの順序に応じて、私の答えは不穏に遅くなる可能性があります。 – TheJacobTaylor
@TheJacobTaylor正解ですが短いコードです。機能的な 'select distinct'型のクエリを置くと、私の+1が得られます。また、これを修正することができれば、光沢のある+1が得られチェック! ;))http://stackoverflow.com/questions/13689434/update-all-rows-with-countdistinct-only-updates-first-row-the-rest-0 –
これを行う簡単な方法はありません。以下のようなもの自体にテーブルを外部結合、私はあなたが(左)に必要と言うだろう、ランクを取得するにはhttp://rpbouman.blogspot.com/2008/07/calculating-nth-percentile-in-mysql.html
私が探しているものは実際にはその逆数です。すなわち、数字を与えれば、そのランクを教えてください。私はこれがOracleでより簡単になると確信していますが、残念ながらそれは可能性はありません。 – lhahne
を参照してください。行ごとに
select t1.name, t1.value, count(distinct isnull(t2.value,0))
from table t1
left join table t2
on t1.value>t2.value
group by t1.name, t1.value
、あなたはどのように多くの(もしあれば)カウントされます同じテーブルの行には値が劣ります。
私はsqlserverに詳しいので、構文が正しくない可能性があることに注意してください。また、別名は、あなたが達成したいことに対して正しい行動をしていないかもしれません。しかしそれは一般的な考えです。
実際のパーセンタイルのランクを取得するには、まず変数の値の数を取得し、上記の実数のランクを使用してパーセンタイルのランクを計算する必要があります。
あなたはPHPのような手続き型言語を使用してSQLを組み合わせている場合は、次の操作を行うことができます。この例では、超過した飛行ブロック時間を空港に分けてパーセンタイルに分解します。 MySQLのLIMIT x、y句をORDER BY
と組み合わせて使用します。 (申し訳ありませんフォーマットに苦労し)非常にきれいな、しかし仕事をしていませんではない:
$startDt = "2011-01-01";
$endDt = "2011-02-28";
$arrPort= 'JFK';
$strSQL = "SELECT COUNT(*) as TotFlights FROM FIDS where depdt >= '$startDt' And depdt <= '$endDt' and ArrPort='$arrPort'";
if (!($queryResult = mysql_query($strSQL, $con))) {
echo $strSQL . " FAILED\n"; echo mysql_error();
exit(0);
}
$totFlights=0;
while($fltRow=mysql_fetch_array($queryResult)) {
echo "Total Flights into " . $arrPort . " = " . $fltRow['TotFlights'];
$totFlights = $fltRow['TotFlights'];
/* 1906 flights. Percentile 90 = int(0.9 * 1906). */
for ($x = 1; $x<=10; $x++) {
$pctlPosn = $totFlights - intval(($x/10) * $totFlights);
echo "PCTL POSN for " . $x * 10 . " IS " . $pctlPosn . "\t";
$pctlSQL = "SELECT (ablk-sblk) as ExcessBlk from FIDS where ArrPort='" . $arrPort . "' order by ExcessBlk DESC limit " . $pctlPosn . ",1;";
if (!($query2Result = mysql_query($pctlSQL, $con))) {
echo $pctlSQL . " FAILED\n";
echo mysql_error();
exit(0);
}
while ($pctlRow = mysql_fetch_array($query2Result)) {
echo "Excess Block is :" . $pctlRow['ExcessBlk'] . "\n";
}
}
}
ここで参加を必要としない別のアプローチがあります。私の場合(1万5千以上の行)のテーブルでは、約3秒で実行されます。 (JOINメソッドのほうが長くなります)。このため
SELECT
id,
@prev := @curr as prev,
@curr := measure as curr,
@rank := IF(@prev > @curr, @[email protected], @rank) AS rank,
@ties := IF(@prev = @curr, @ties+1, 1) AS ties,
(1[email protected]/@total) as percentrank
FROM
mytable,
(SELECT
@curr := null,
@prev := null,
@rank := 0,
@ties := 1,
@total := count(*) from mytable where measure is not null
) b
WHERE
measure is not null
ORDER BY
measure DESC
クレジット:サンプルで
は、 対策はあなたがパーセント・ランクを計算しているどの列があり、かつ IDは(必須ではありません)だけ行識別子であることを前提としてい方法はShlomi Noachに行く。彼はここでは詳細にそれについて書いている:私は、MySQLでこれをテストしてみた、それは素晴らしい作品http://code.openark.org/blog/mysql/sql-ranking-without-self-join
。 Oracle、SQLServerなどについては考えていません。
これは非常にうまく動作します。 Genius SQL。 –
残念ながら、これは未定義の動作であるユーザー変数の評価の順序によって異なります。そのリンクの最初のコメントはMySQLのマニュアルを引用しています: "ユーザ変数の評価の順序は未定義であり、与えられたクエリに含まれる要素に基づいて変更されるかもしれません....一般的な規則は決してユーザ変数同じステートメントの他の部分で同じ変数を使用すると、期待通りの結果が得られるかもしれませんが、これは保証されていません」 リファレンス:http://dev.mysql.com/doc/refman/5.1/en/user-variables.html – rep
SELECT
c.id, c.score, ROUND(((@rank - rank)/@rank) * 100, 2) AS percentile_rank
FROM
(SELECT
*,
@prev:[email protected],
@curr:=a.score,
@rank:=IF(@prev = @curr, @rank, @rank + 1) AS rank
FROM
(SELECT id, score FROM mytable) AS a,
(SELECT @curr:= null, @prev:= null, @rank:= 0) AS b
ORDER BY score DESC) AS c;
- 1. mysqlの計算
- 2. MySQLの計算は
- 3. 計算 - PHP/MySQLの
- 4. Mysqlの計算カラム
- 5. クロステーブルのmysql計算
- 6. mysqlワークベンチプロシージャの計算
- 7. MySQLの計算分
- 8. mysql - 計算
- 9. 計算とMYSQL
- 10. Mysql計算サブクエリ
- 11. MySQLの計算能力
- 12. MySQLの投票計算
- 13. mysqlの重い計算
- 14. 合計超過時間の計算MySQL
- 15. 計算 - PHP/MySQLは
- 16. MySQLでの距離計算の距離計算
- 17. MySQLの前の行の計算
- 18. YSQLを計算するMYSQL
- 19. 計算されたMYSQL列
- 20. 道路距離計算mysql
- 21. Mysqlの時間計算 - 時間のみ
- 22. MySQLの時間の計算時に
- 23. mysqlの計算カラムの再利用
- 24. は、MySQLテーブルの計算のよう
- 25. MySQLのPHPの合計()乗算?
- 26. where節のMySQLの計算結果?
- 27. MySQLのセレクト&リミット計算の複雑
- 28. MySQLの時間/日付計算
- 29. MySQLのタイムスパンを2回計算する
- 30. MySQLのノルム分布を計算する
パーセンタイルランクの意味を正確に説明できますか? –
@AssafLavie:http://en.wikipedia.org/wiki/Percentile_rank – eliasah
すべてのパーセンタイルで機能するMysql関数を作成しました: http://stackoverflow.com/a/40266115/1662956 – dartaloufe