0

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

示例时间:

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

另一个例子可能是:

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

现在我的问题是:
我应该在 PHP 还是 MySQL 中执行此操作?(我当时认为 MySQL 可能会更快)
在 MySQL 中是否有更好(更有效)的方法来执行此操作,而不是为每一行生成随机数并按此排序行,然后使用 OFFSET 和 LIMIT 来选择行?

4

2 回答 2

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;
于 2013-09-03T00:54:32.157 回答
0

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

SELECT * FROM players
ORDER BY rand()

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

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

于 2013-09-03T00:00:01.047 回答