SQL查询根据获胜赔率找到胜利者

时间:2012-11-07 20:14:31

标签: mysql sql

我需要SQL查询来确定随机获胜者。每个用户都拥有自己的胜算。 wins_odds值越高,用户获胜的机会就越多。以下是表结构:

id    email            winning_odds
1     test@test.com    3
2     test2@test.com   5
3     test3@test.com   2
4     test4@test.com   1
5     test5@test.com   9

MySQL数据库。表有大约100000行。只有一个赢家,一次。电子邮件是独一无二的。有人有解决方案吗?

感谢。

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

我真的很喜欢这个问题,我发布了postgresql的答案。

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

这是它的工作原理。对于表格的每一行,我们将该行复制N次作为您的获胜赔率。

因此,您首先获得并且不限制查询结果:

  5 | test5@test.com |    9 | 9
  2 | test2@test.com |    5 | 3
  3 | test3@test.com |    2 | 1
  1 | test@test.com  |    3 | 1
  5 | test5@test.com |    9 | 5
  1 | test@test.com  |    3 | 3
  5 | test5@test.com |    9 | 2
  2 | test2@test.com |    5 | 4
  2 | test2@test.com |    5 | 5
  5 | test5@test.com |    9 | 1
  4 | test4@test.com |    1 | 1
  5 | test5@test.com |    9 | 7
  5 | test5@test.com |    9 | 4
  5 | test5@test.com |    9 | 6
  2 | test2@test.com |    5 | 1
  5 | test5@test.com |    9 | 8
  3 | test3@test.com |    2 | 2
  1 | test@test.com  |    3 | 2
  2 | test2@test.com |    5 | 2
  5 | test5@test.com |    9 | 3

现在,随机选择生成的表格中的任何一行都会反映出wins_odds字段的概率。

您所要做的就是随机订购并获得第一张唱片。

 9 | test5@test.com |    9 | 2 

此致

答案 2 :(得分: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没有一种有效的方法。

如何优化查询取决于问题中的某些其他因素。 “赔率”有多少不同的值?你能用临时表吗?

我现在没有时间写出解决方案,但有一种更有效的方法。 Y的想法是将问题分成两个搜索。第一个将找到哪个“赔率”值获胜。第二个将找到哪一行获胜。

以下是详细信息:

(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

答案 3 :(得分:0)

如果我正确理解了这个问题,你就会问如何从表中选择一个随机记录。这应该有效:

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

现在还清楚你打算如何使用winner_odds值。