我正在使用MySQL ver 5.5.8。
让我说我有表,条目,结构如下:
entry_id int PK
member_id FK
每个成员可以有多个条目。我希望随机获得其中的10个,但我需要以允许被选中的几率随成员的条目数增加的方式获取它们。我知道我可以这样做:
SELECT member_id
FROM entries
GROUP BY member_id
ORDER BY RAND()
LIMIT 10
但我不确定这是否能满足我的需求。 MySQL会将记录分组然后选择10吗?如果是这样的话那么每个成员都有同样的机会被选中,这不是我想要的。我做了一些测试和搜索,但无法得出明确的答案。有谁知道这会做我想做的事情还是我必须以不同的方式做事情?任何帮助,将不胜感激。非常感谢!
答案 0 :(得分:1)
LIMIT 10
将选择10条记录(在本例中为)随机顺序。这确实是在分组之后。
也许你可以ORDER BY RAND() / count(*)
。这样,对于有更多问题的用户来说,这个数字可能会更小,因此他们更有可能进入前10名。
[编辑]
顺便说一句,似乎随着时间的推移(随着数据的增长)ORDER BY RAND()
变慢。有几种方法可以解决这个问题。 Mediawiki(维基百科背后的软件)有一个有趣的方法:它为每个页面生成一个随机数,所以当你选择“随机页面”时,它会生成一个0到1之间的随机数,并选择最接近该数字的页面: / p>
WHERE number > {randomNumber} ORDER BY number LIMIT 1`
节省了必须为每个查询生成临时表。如果数据增长,您将需要定期重新生成数字,并且必须确保均匀生成数字。这很容易:对于新记录,您只需生成一个随机数。定期更新整个列表:查询所有记录。然后,按顺序为每个记录分配一个介于0和1之间的数字,但是在递增数字中,会增加1 / recordCount
。这样,记录间隔均匀,找到它们的变化对于每一个都是相同的。
您也可以使用该方法。从长远来看,它会使您的查询更快,并且您可以使分发更加智能:1)您可以使用'totalEntryCount'而不是使用'memberCount'。 2)您可以使用1 / 'memberCount'
,而不是按entryCountForMember / totalEntryCount
递增。这样,具有更多条目的成员之前的差距将更大,因此,它们匹配随机数的机会也将更大。例如,您的成员可能如下所示:
name entries number delta
bob 10 0.1 0.10
john 1 0.11 0.01
jim 5 0.16 0.05
fred 84 1 0.84
当然,不会保存增量,但会显示添加的数字。在Mediawiki示例中,每个页面的增量都是相同的,但在您的情况下,它可能取决于条目的数量。现在你看,bob和john之间只有一个小的差距,所以你在0和bob之间选择一个随机数的几率是在bob和john之间选择一个随机数的十倍。因此,采摘鲍勃的几率是采摘约翰的十倍。
您需要一个(cron)作业来定期重新分配数字,因为您不希望在每次修改时都这样做,但对于您正在处理的数据类型,它不一定是真实的-time,如果您有许多成员和许多条目,它会使您的查询更快。