从包含已删除记录的表中随机选择行


Select random row from table with deleted records

如果我有一个包含 3 行 ID 为 1,3,5 的表,因为删除了 ID 为 2 和 4 的行,如何确保我选择了存在的行?

$stmt = $db->prepare("SELECT COUNT(*) FROM table");
$stmt->execute();
$stmt->bind_result($numRows);
$stmt->fetch();
$stmt->close();
$random = mt_rand(1,$numRows);
$stmt = $db->prepare("SELECT link FROM table WHERE id=$random");

这永远不会选择ID 为 5 的行,并且还会选择一个不存在的行 (2)。

如果行数很少(并且您确定它将保持这种状态),则可以使用ORDER BY RAND()(请注意,这将导致大表的性能问题)。

另一种方法是首先计算有多少行

选择 计数(*) 作为表中的总计;

然后选择一个随机数

$rand = 兰德(1, $total);

,然后选择有限制的行

从表限制中选择 * 限制 $rand, 1;

你可以将SQL语句与EXIST一起使用

SELECT link
FROM table
WHERE EXISTS (SELECT link
              FROM table
              WHERE id = $random);

如果你只想要一个随机行而不关心 id,那么你可以使用:

SELECT link FROM table
ORDER BY RAND()
LIMIT 1

对于大量行 (10000+),您可能需要实现另一个解决方案,因为此查询可能很慢。这个网站有一个很好的解释和替代解决方案

如果你想遵循你的方法,那么你必须在你的查询中进行一些更改。

1.) Query one : select id from table. // It will give you array of existing id.
2.) You have to use array_rand(). and use your second query.

例:

$stmt = $db->prepare("SELECT ID FROM table");
$result = $stmt->fetchAll();
$random = array_rand(array_flip($result), 1);
$stmt = $db->prepare("SELECT link FROM table WHERE id=$random");

您可以选择一个随机排序,如下所示:

SELECT link FROM table ORDER BY RAND() LIMIT 1

更新:您应该对您拥有的不同解决方案进行基准测试,但我认为这个解决方案对于大量行来说可能很好:

$stmt = $db->prepare("SELECT COUNT(*) FROM table");
$stmt->execute();
$stmt->bind_result($numRows);
$stmt->fetch();
$stmt->close();
$random = mt_rand(1,$numRows);
$stmt = $db->prepare("SELECT link FROM table WHERE id>=$random LIMIT 1");
$stmt->execute();
$stmt->bind_result($link);
if(!$link){
    $stmt = $db->prepare("SELECT link FROM table WHERE id<$random LIMIT 1");
    $stmt->execute();
    $stmt->bind_result($link);
}