note 71153 deleted from function.rand by felipe

From: 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 ;)

« previous php.notes (#134444) next »