在 MySQL 中选择随机行

Posted

技术标签:

【中文标题】在 MySQL 中选择随机行【英文标题】:Selecting Random Rows in MySQL 【发布时间】:2010-11-19 23:56:12 【问题描述】:

我正在开发一个测验网站,我有一个存储所有问题的数据库。 有不同类型的测验,例如数学、科学、历史等。所有问题都存储在一个表格中。

我的问题表如下所示:

questions ( qno(int)  ,type(int), question, .... ,... )

qno 是主键,type 用于跟踪测验类型。:

if type = 1 (math)
 type = 2(science)

现在,我想为每种类型的测试选择一些随机问题。 例如,我可能想为数学测试随机选择一些 20 个问题。

mysql 有什么方法可以选择随机行吗?

【问题讨论】:

复制How to request a random row in SQL?,quick selection of a random row from a large table in mysql。 MySQL select 10 random rows from 600K rows fast 【参考方案1】:

选择可能重复的随机行数

Select Cus_Id from Customer
Where Cus_Id in (
SELECT ABS(CHECKSUM(NewId())) % (select COUNT(*) from Customer) - 0 AS Random FROM Customer)

如果你想从某个点开始(id 1500 及以上到更窄的范围

Select Cus_Id from Customer
Where Cus_Id in (
SELECT ABS(CHECKSUM(NewId())) % (select COUNT(*)+1500 from Customer) - 1300 AS Random FROM Customer)

如果您想要更少,可以添加 SELECT TOP x 或 TOP x PERCENT

【讨论】:

【参考方案2】:

另一种可能性是生成random permutation,将其存储在会话中(或只是您需要的部分,算法很容易适应),并在需要时获取问题。

【讨论】:

【参考方案3】:

向您的表中添加一个包含 UNIX 时间戳的列。

您可以在一天或任何适合您的时间范围内运行一次更新该列的查询。

在这种情况下,您的查询应该在午夜运行,看起来像这样。

UPDATE table SET rand_id = (UNIX_TIMESTAMP() + (RAND() * 86400));

然后要检索行,您可以使用与此类似的查询。

SELECT * FROM table WHERE rand_id > UNIX_TIMESTAMP() ORDER BY rand_id ASC LIMIT 20

使用具有预先确定的随机值的列,您无需为页面的每个请求为表中的每一行运行随机化函数。

【讨论】:

【参考方案4】:

您可以使用 MySQL 中的 rand 函数对行进行排序,然后使用 limit 获取前 10 名(或任意数量)。

select * from table order by rand() limit 10

如果你只想要数学问题:

select * from table where type = 1 order by rand() limit 10

【讨论】:

请参阅我想一次向用户显示一个问题。所以我在想,当测验开始时我将使用上述查询,然后我将在会话中存储所有问题,然后我将通过每次使用新查询来验证每个问题。这是正确的方法吗? 如果您只想每页一个问题,只需使用limit 1 而不是limit 10 将该用户看到的问题存储在一个表中,然后构造这个查询左连接到该表并且看到的表的字段为空。 您可以使用 php 会话来维护该会话中提出的问题的历史记录。每次查询随机问题时,添加“WHERE QuestionID NOT IN (previous_asked_question_ids)”子句。

以上是关于在 MySQL 中选择随机行的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 从 600K 行中快速选择 10 个随机行

从文件中选择随机行

在 Oracle 中选择随机行

MySQL - 从大表中选择随机行

在 MySQL 中选择随机行

从 SQL Server 表中选择 n 个随机行