6

cur_oddsという行を持つMySQLテーブルがあります。これは、その行が選択される確率をパーセントで表したパーセント値です。たとえば、100個のクエリを実行したときに、ほぼその頻度で実際に行を選択するクエリを作成するにはどうすればよいですか?

次のことを試しましたが、確率が0.35の行は、60〜70%の確率で選択されてしまいます。

SELECT * FROM table ORDER BY RAND()*cur_odds DESC

テーブル内のcur_oddsのすべての値は、正確に1になります。

4

2 に答える 2

4

がめったに変更されない場合cur_oddsは、次のアルゴリズムを実装できます。

1) 別の列prob_sumを作成します。

prob_sum[0] := cur_odds[0]

1 <= i <= row_count - 1 の場合:

prob_sum[i] := prob_sum[i - 1] + cur_odds[i]

2) 0 から 1 までの乱数を生成します。

rnd := ランド(0,1)

3) 次の最初の行を見つけprob_sum > rndます ( で BTREE インデックスを作成するprob_sumと、クエリはより高速に動作するはずです)。

CREATE INDEX prob_sum_ind ON <テーブル> (prob_sum);

SET @rnd := RAND();

SELECT MIN(prob_sum) FROM <テーブル> WHERE prob_sum > @rnd;

于 2010-04-26T20:47:36.850 に答える
4

上記のSQLステートメントを考えると、あなたが持っている数値は、各行が選択される確率ではなく、代わりに相対として最もよく解釈できる(他のすべての行の「重み」に対して)任意のcur_odds重み付けですソートされたテーブルの上部に向かって浮く傾向があります。各行の実際の値は無意味です (たとえば、値が 0.35、0.5、0.75、および 0.99 の 4 つの行がある場合や、値が 35、50、75、および 99 の場合、結果は同じになります)。

更新: クエリで何が起こっているかを次に示します。cur_odds値が 0.35 の行が 1 つあります。説明のために、残りの 9 行はすべて同じ値 (0.072) であると仮定します。また、説明のために、RAND() が 0.0 から 1.0 までの値を返すと仮定しましょう (実際にはそうかもしれません)。

この SELECT ステートメントを実行するたびに、そのcur_odds値に 0.0 から 1.0 までの RAND() 値を乗算することによって、各行に並べ替え値が割り当てられます。これは、0.35 の行が 0.0 から 0.35 の間のソート値を持つことを意味します。

1 つおきの行 (値が 0.072) には、0.0 から 0.072 の範囲の並べ替え値があります。これは、ある行の並べ替え値が 0.072 より大きい可能性が約 80% あることを意味します。つまり、他の行がより高く並べ替えられる可能性はありません。cur_oddsこれが、値が 0.35 の行が予想よりも頻繁に最初に表示される理由です。

cur_odds値を相対的な変化の重み付けと誤って説明しました。これは実際には最大相対重み付けとして機能し、関連する実際の相対確率を決定するためにいくつかの複雑な計算が必要になります。

ストレートな T-SQL で何が必要なのかわかりません。私は加重確率ピッカーを何度も実装してきましたが (皮肉なことに、今朝、これに最適な方法について質問するつもりでさえありました)、常にコードで実装しました。

于 2010-04-26T19:23:02.900 に答える