note 71153 added to function.rand

From: Date: Tue, 14 Nov 2006 08:32:47 +0000
Subject: note 71153 added to function.rand
Groups: php.notes 
Request: Send a blank email to php-notes+get-119708@lists.php.net to get a copy of this message
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 ;) ---- Server IP: 83.138.144.80 Probable Submitter: 213.120.98.128 ---- Manual Page -- http://www.php.net/manual/en/function.rand.php Edit -- https://master.php.net/note/edit/71153 Del: integrated -- https://master.php.net/note/delete/71153/integrated Del: useless -- https://master.php.net/note/delete/71153/useless Del: bad code -- https://master.php.net/note/delete/71153/bad+code Del: spam -- https://master.php.net/note/delete/71153/spam Del: non-english -- https://master.php.net/note/delete/71153/non-english Del: in docs -- https://master.php.net/note/delete/71153/in+docs Del: other reasons-- https://master.php.net/note/delete/71153 Reject -- https://master.php.net/note/reject/71153 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#119708) next »