note 71153 deleted from function.rand by felipe
| From: | felipe@php.net | Date: | Sun, 30 Dec 2007 18:45:11 +0000 |
| Subject: | note 71153 deleted from function.rand by felipe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-134444@lists.php.net to get a copy of this message | ||
Note Submitter: dsoussan at gmail dot com
----
The problem with these random row functions below is that they require you to fetch all the query
results first. Now this may be OK for a small resultset - but in that case why not just use the SQL
'ORDER BY RAND() LIMIT 10' to do the job.
The real problem arises when you want a small random selection from a large query resultset; in that
case the SQL RAND() function causes the query to run very slowly. It is then that we need to do the
processing in php, and fetching every row from a large query resultset first rather defeats the
purpose.
The following is a far simpler and more efficient solution to this problem. It will also cope with
queries that do not return distinct rows.
<?php
function randomselection($c, $sql) {
// run the query
$result=mysql_query($sql) or die($sql);
// get the upper limit for rand()
$up = mysql_num_rows($result)-1;
// check that there is more data than rows required
if ($up <= $c) {
while ($row=mysql_fetch_assoc($result)) {
$selection[] = $row;
}
return $selection;
}
// set up array to hold primary keys and elliminate duplicates
// since random DOES NOT mean unique
// or the query may not return DISTINCT rows
$keys = array();
// get random selection
while (count($keys) < $c) {
// get random number for index
$i = rand(0, $up);
// move pointer to that row number and fetch the data
mysql_data_seek($result, $i);
$row = mysql_fetch_assoc($result);
// check if the primary key has already been fetched
if (!in_array($row['id'], $keys)) {
// store the row
$selection[] = $row;
// store the id to prevent duplication
$keys[] = $row['id'];
}
}
return $selection;
}
?>
Fully tested and certified bug-free ;)