如何从SQL查询选择中选择随机行?

时间:2013-05-16 19:46:40

标签: php html mysql sql

如何从SQL数据库查询中随机选择一行?我的意思是:

选择所有类别'绿色'来自table1:

$stmt = $db->query('SELECT * from table1 WHERE Category LIKE "%green%"');

然后从该选择中随机显示一行(而不是显示此选择中的每一行,如下所示)

while($rows = $stmt->fetch()){
     echo "<tr><td>". $rows['Number'] . "</td><td>" . $rows['Content'] . "</td></tr>";
};

4 个答案:

答案 0 :(得分:5)

在合理大小的数据集中,随机排序并选择第一个:

...ORDER BY RAND() LIMIT 1;

您的陈述将成为:

$stmt = $db->query(
    'SELECT * from table1
     WHERE Category LIKE "%green%"
     ORDER BY RAND() LIMIT 1;'
);

如果在查询中缩小选择范围,则无需使用混乱的过程从PHP代码中的结果集中提取单行。

如果您的数据集非常大,请考虑按照Tobias Hagenbeek的建议执行多个查询:

  1. COUNT()匹配的行。
  2. 在PHP中,选择介于1和COUNT()结果之间的随机数。
  3. 执行新查询以选择指定的行:

    ...LIMIT <random number>, 1;

  4. 最后,如果您只需要一个任意行,并且随机性/唯一性不是问题,请考虑每次按照Gordon Linoff的建议从表中选择第一行:

    ...LIMIT 1;
    

答案 1 :(得分:0)

简单的方法是:

$stmt = $db->query('SELECT * from table1 WHERE Category LIKE "%green%" ORDER BY RAND()');

ORDER BY RAND()会随机排序结果,但作为一项操作(link)有点贵。

如果您关心这类事情,您可以选择查询表格中的行数,然后在查询结尾处$r = rand(0, $count-1),然后LIMIT 1 OFFSET $r

答案 2 :(得分:0)

你可以使用ORDER BY RAND(),但你应该厌倦这样做。特别是如果你正在谈论大型系统,并且超过10k行。

这就是为什么......

运行此类查询时会发生什么?假设您在具有10000行的表上运行此查询,而不是SQL服务器生成10000个随机数,扫描此数字以获取最小值并为您提供此行。生成随机数是相对昂贵的操作,扫描它们为最低的一个(如果你有LIMIT 10,它需要找到10个最小的数字)也不是那么快(如果引用是文本它更慢,如果它是固定大小的东西它更快,可能是因为需要创建临时表)。

所以你应该做的是对你的行进行计数,在0和你的count-1之间取一个随机数,然后做 SELECT列FROM表LIMIT $ generated_number,1

答案 3 :(得分:0)

如果您只想要所有行的一行,那么最快的方法就是:

 SELECT *
 from table1
 WHERE Category LIKE "%green%"
 LIMIT 1;

这将为您提供数据中遇到的第一行。为了近似,这是插入表中符合条件的第一行。 (这是的保证。例如,删除肯定会改变这一点。)

这有一个快捷的优点,这很有用,因为索引不会对where子句有益。在这种情况下,查询执行全表扫描,但在第一次匹配时停止。

真正随机行的替代方法是使用rand()

SELECT *
from table1
WHERE Category LIKE "%green%"
order by rand()
limit 1;

这需要一个不会停止的全表扫描,因为排序需要所有匹配。然后,您需要通过rand()对子集进行排序的额外开销。如果性能确实存在问题,还有一些替代方案。