Maybe the following.
$results = mysql_query("SELECT column1, column2, date, time FROM table LIMIT RAND(),1");
$row_table = mysql_fetch_assoc($results);
If that fails to return a row then rand() is returning a number higher than the number of rows present.
cwarn23
Occupation: Genius
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
To make things easier the following.
$results = mysql_query("SELECT column1, column2, date, time FROM table LIMIT ROUND(RAND(COUNT(*))),1");
$row_table = mysql_fetch_assoc($results);
cwarn23
Occupation: Genius
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
Maybe we should start by asking whatt you are trying to accomplish with this query.
"Order BY" refers to how mysql returns the sort order. How does a random floating point between 0 and one do anything useful in this context?
I wonder how how you got any results at all.
JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
Try each of the following
$results = mysql_query("SELECT * FROM table ORDER BY RAND() LIMIT 0,1");
$row_table = mysql_fetch_row($results);
$results = mysql_query("SELECT * FROM table ORDER BY RAND() LIMIT 2");
$row_table = mysql_fetch_row($results);
$results = mysql_query("SELECT * FROM table ORDER BY RAND() LIMIT 1,1");
$row_table = mysql_fetch_row($results);
My theory is that the limit 1 statment wasn't designed to be ordered by random. But maybe we can make a work around this bug.
cwarn23
Occupation: Genius
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
Tried back-ticking your fields? I don't know if it will make any difference. I know that DATE and TIME have a particular meaning in MySQL.
diafol
Rhod Gilbert Fan (ardav)
7,765 posts since Oct 2006
Reputation Points: 1,168
Solved Threads: 1,075
OK, let's assume that it is ordering by id which is a primary key.
Primary keys are INTEGERS, not floating point decimals >0 , <=1.
if you want to randomize an integer result you would have to multiply by ten then round up to the nearest integer value. Use that as your selection.
However you are randomizing the sort, not the selection.
If you want a different id every time, why not use WHERE id = $someRandomInteger
You won't need to limit, because the id is unique.
JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
OK, let's assume that it is ordering by id which is a primary key.
Primary keys are INTEGERS, not floating point decimals >0 , <=1.
if you want to randomize an integer result you would have to multiply by ten then round up to the nearest integer value. Use that as your selection.
However you are randomizing the sort, not the selection.
If you want a different id every time, why not use WHERE id = $someRandomInteger
You won't need to limit, because the id is unique.
This'll work if the Primary Key series is complete. What if some keys have been deleted, e.g. 1,2,3,5,8,...?
Interesting discussion here: http://www.greggdev.com/web/articles.php?id=6
I've seen the offset method used too
The offset keyword tells the query to select the next x record after the first. If offset = 0, the return the first, if offset = 2, return the 3rd etc. So for this, get the random number to be between 0 and no_rows -1, then apply this to the offset. This may mean running 2 queries. Perhaps they could be nested??
diafol
Rhod Gilbert Fan (ardav)
7,765 posts since Oct 2006
Reputation Points: 1,168
Solved Threads: 1,075
JRM,
The query is for recommendations, it is meant to randomize the results to get something different each time. Thus, the order by rand. By default how is a query ordered, by id I would assume? Doesn't do me much good if it displays the same values every time does it? If you have a better way I'm all ears.
You asked if there is something wrong with this query,
The entire premise is faulty. As i said, I'm surprised that it works at all albeit "randomly".
Order by is used for making a column as the one for the sort ORDER output, such as ORDER BY name asc, which will sort the output rows by all the names in the query alphabetically. "Order by" implies more than one row!!!
Order and Section criteria are two different things?
If you want to output ONE recommendation, why not select one primary key Randomly?
$results = mysql_query("SELECT * FROM table where id = $someRandomNumber");
$row_table = mysql_fetch_row($results);
Where you will have to take that floating point output from rand which by the way,is >0 but <= 1 multiply it by 10 and round up to the nearest INTEGER. ( Isn't there something better than rand()???) Use the integer output to select the primary key key on a row in the table.
JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
Here's the OFFSET idea. This prevents having to go through a whole table scan (*I think*).
$n = mysql_query("SELECT COUNT(*) FROM table");
$off = mysql_fetch_array($n);
$max_offset = $off[0] - 1;
$rnd = mt_rand(0,$max_offset);
$rs = mysql_query("SELECT fields FROM table LIMIT 1 OFFSET $rnd");
$data = mysql_fetch_array($rs);
It would be interesting to see how quickly this would run in comparison with the mysql RAND function. I think this may be a preferred method as it doesn't depend on the actual primary key value. i.e. you don't need to know it and your series (min to max) does not have to be continuous (every inbetween integer). Anyway, interesting to hear from others on this.
//EDIT: the last query ran at about 62ms for a db with 5200 records, and worked a treat!
diafol
Rhod Gilbert Fan (ardav)
7,765 posts since Oct 2006
Reputation Points: 1,168
Solved Threads: 1,075
Here's the OFFSET idea. This prevents having to go through a whole table scan (*I think*).
$n = mysql_query("SELECT COUNT(*) FROM table");
$off = mysql_fetch_array($n);
$max_offset = $off[0] - 1;
$rnd = mt_rand(0,$max_offset);
$rs = mysql_query("SELECT fields FROM table LIMIT 1 OFFSET $rnd");
$data = mysql_fetch_array($rs);
It would be interesting to see how quickly this would run in comparison with the mysql RAND function. I think this may be a preferred method as it doesn't depend on the actual primary key value. i.e. you don't need to know it and your series (min to max) does not have to be continuous (every inbetween integer). Anyway, interesting to hear from others on this.
//EDIT: the last query ran at about 62ms for a db with 5200 records, and worked a treat!
...now THAT's what I'm talkin' 'bout!
Makes perfect sense...and no rand()
Very good info,ardav.
I'm going to keep this script in mind if I ever need random sampling in the future.
JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
Yep, took me a while to get to grips with it. I was working on a vague recollection of something I saw a year or two ago! It's a beauty - although I can't claim all the credit - the seed was sown by others. I'm sure that there are other implementations out there somewhere, but I'm blasted if I can find them now.
diafol
Rhod Gilbert Fan (ardav)
7,765 posts since Oct 2006
Reputation Points: 1,168
Solved Threads: 1,075