在MySQL中为n个组选择随机子集

时间:2013-09-02 23:43:52

标签: php mysql sql random

我有一个MySQL表players,我试图将所有玩家随机放入n组(n> = 2),其中每组都有一个确定但可变的大小。

示例时间:

将表players中的10.000行放入3组,其中A组包含5.000名玩家,B组包含3.000名玩家,C组包含2.000名玩家。

另一个例子可能是:

将表players中的10.000行分为4组,其中A组包含3.000名玩家,B组包含3.000名玩家,C组包含2.000名玩家,D组包含2.000名玩家。

现在我的问题:
我应该在PHP或MySQL中这样做吗? (我以为MySQL可能会更快) 在MySQL中有更好(更有效)的方法,而不是为每行生成随机数并按行排序,然后使用OFFSET和LIMIT来选择行吗?

2 个答案:

答案 0 :(得分:0)

我认为最有效和最简单的方法是运行此查询:

SELECT * FROM players
ORDER BY rand()

然后在几个PHP FOR循环中迭代结果(每个组一个)。

这样,您将只运行一个查询并迭代结果一次(这实际上是您必须要做的事情)。

答案 1 :(得分:0)

您可以在MySQL中执行此操作。策略如下。随机化行并枚举它们。然后计算每个组的枚举中断。

select t.*,
       (case when (seqnum - 1) / totalcnt < 0.3 then 'GroupA'
             when (seqnum - 1) / totalcnt < 0.6 then 'GroupB'
             when (seqnum - 1) / totalcnt < 0.8 then 'GroupC'
             else 'GroupD'
        end) as WhichGroup
from (select t.*, @rn := @rn + 1 as seqnum, totalcnt
      from t cross join
           (select @rn := 0, count(*) as totalcnt from t) const
      order by rand()
     ) t;

order by rand()确实减慢了速度。但是,获取随机样本并不是一个固有的快速过程。

更快的方法 - 创建与您要查找的组略有不同的组 - 是执行以下操作:

select t.*,
       (case when rand() < 0.3 then 'GroupA'
             when rand() < 0.6 then 'GroupB'
             when rand() < 0.8 then 'GroupC'
             else 'GroupD'
        end) as WhichGroup
from t;