如果我有一个包含 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);
}