2012-11-07 70 views
1

我需要一個SQL查詢來確定隨機贏家。每個用戶都有自己的勝算。勝利值越高,用戶贏得的機會就越多。這裏看看錶結構:SQL查詢根據獲勝賠率找到贏家

id email   winning_odds 
1  [email protected] 3 
2  [email protected] 5 
3  [email protected] 2 
4  [email protected] 1 
5  [email protected] 9 

MySQL數據庫。表格大約有100000行。一次只有一個贏家。電子郵件是唯一的。任何人都有解決方案?

謝謝。

+1

什麼那些勝算呢?你打算如何使用它們?你有什麼嘗試? –

+0

你正在使用什麼數據庫? – andrefsp

+0

嗨,賠率意味着每個用戶的獲勝機會。我正在使用MySQL數據庫。 –

回答

0

如果我正確地理解了這個問題,您正在問如何從表中選擇一個隨機記錄。這應該工作:

SELECT * 
FROM tableName 
ORDER BY RAND() LIMIT 0,1; 

現在仍清除你打算如何計劃用戶的winning_odds值。

+0

勝利越高,用戶獲勝的機會就越多。 –

1

Select email from user order by winning_odds*rand() limit 1

+0

我無法弄清楚這是否有竅門。我不這麼認爲,是嗎? –

+0

它是否正常工作取決於您希望wins_odds如何在數量上影響每個用戶獲勝的百分比機會。如果你所關心的是具有更高勝率的用戶有更高的獲勝機率,那麼是的,這是有效的。 – histocrat

+0

5 * rand()是5到9,可能高於9 * Rand()。它簡單而優雅,最重要的作品。 – jTC

1

我真的很喜歡這個問題,我張貼PostgreSQL的答案。

select 
    *, generate_series(1, mytable.winning_odds) 
from 
    mytable 
order by 
    random() 
limit 1; 

這是如何工作的。對於你的表中的每一行,我們複製第N行作爲你贏的賠率。

所以,你得到的第一和不限制查詢結果:

5 | [email protected] | 9 | 9 
    2 | [email protected] | 5 | 3 
    3 | [email protected] | 2 | 1 
    1 | [email protected] | 3 | 1 
    5 | [email protected] | 9 | 5 
    1 | [email protected] | 3 | 3 
    5 | [email protected] | 9 | 2 
    2 | [email protected] | 5 | 4 
    2 | [email protected] | 5 | 5 
    5 | [email protected] | 9 | 1 
    4 | [email protected] | 1 | 1 
    5 | [email protected] | 9 | 7 
    5 | [email protected] | 9 | 4 
    5 | [email protected] | 9 | 6 
    2 | [email protected] | 5 | 1 
    5 | [email protected] | 9 | 8 
    3 | [email protected] | 2 | 2 
    1 | [email protected] | 3 | 2 
    2 | [email protected] | 5 | 2 
    5 | [email protected] | 9 | 3 

現在,選擇隨機生成的表格的任意一行將反映你的winning_odds場的概率。

您只需要隨機訂購併獲取第一條記錄。

9 | [email protected] | 9 | 2 

問候

+0

非常感謝,這似乎是一個竅門。太糟糕了,MySQL沒有generate_series功能。我想我將不得不創建另一個模擬它的表格。 –

+0

看看這篇文章http://stackoverflow.com/questions/6870499/generate-series-equivalent-in-mysql它包含如何在mySQL中執行generate_series – andrefsp

1

我猜測,「賠率」是不是整數,你想要的東西,有一個「9」是九倍,比「1」的可能性較大。

這樣做的正確方法是累積和。然後在累計和的最小值和最大值之間生成一個隨機值,並選擇該範圍內的記錄。下面的查詢這是否在MySQL:

select t.* 
from (select t.*, 
      coalesce((select sum(odds) from t t2 where t2.id < t.id), 0) as cumsum, 
      const.sumodds 
     from t cross join 
      (select rand()*sum(odds) as val from t) const 
    ) t 
where val between cumsum and cumsum + t.odds 

然而,這是做非等值連接,並很可能會在MySQL昂貴。其他數據庫有能力在單個查詢中執行累計和。 MySQL沒有這樣做的有效方式。

如何優化查詢取決於問題中的某些其他因素。 「賠率」有多少個不同的值?你可以使用臨時表嗎?

我現在沒有時間寫出解決方案,但有一種更有效的方法。是的想法是將問題分成兩個搜索。第一個會發現哪個「賠率」值勝。第二個將找到哪一行勝出。

下面是詳細信息:

(1)由所述賠率總結數據插入表中。該表格將有11行,幷包含每個行的「可能性」和「計數」。(2)計算每行的「count * odds」的總和,從第一行的0開始計算。你可以使用上面的查詢作爲指導,因爲這是很少量的數據,它會很快運行。

(3)計算一個隨機數爲rand()*<sum of all odds>。現在,找出數字在cumsum和cumsum +賠率之間的機率。

(4)現在返回到原始表併發出一個查詢,如:

select * 
from t 
where odds = <winning odds> 
order by rand() 
limit 1 
+0

感謝您的回答,winning_odds值都是整數。現在在我的表格中,最高值是11,但可能會更高。是的,我可以使用臨時表。 –

+0

感謝您的時間,但是您在第(3)點失去了我。 –