tags:

views:

279

answers:

7

Hello, I'm trying to get a pick from my DB that would last for a day (daily pick). I use the following code:

$query = 'SELECT * FROM table ORDER BY rand() LIMIT 1

But as you can see it only gives me a random pick from the table, and every time I refresh the page it gets me a new random pick. How can I make the pick to last for a whole day?

Thanks in advance <3


I'm trying this now:

$dailyPick = 'SELECT * FROM table ORDER BY rand() LIMIT 1';  

$cacheKey = 'dailyPick'. date('dmY');  
if($cache->has($cacheKey)) {  
    $dailyPick = $cache->get($cacheKey);  
} else {  
    // hit database  
    $dailyPick = $cache->save($cacheKey);  
}  

However, it gets me a mistake that I'm using the 'has' function on a non-object.

+4  A: 

A sane means of doing this would be to automatically generate the pick of the day content via a cron job that was setup to run once a day.

As such, the cron job would execute the SQL you provided and store the appropriate content in a flat file/database table, etc. (or perhaps even just store the choosen id in another table for future lookup purposes).

middaparka
This is the best approach. The random selection is done only once. after this, showing your daily pick is a fast and simple select query.
Jacco
+1  A: 

You can try something like this:

$total = 'SELECT COUNT(*) FROM table;';
$query = 'SELECT * FROM table ORDER BY id ASC LIMIT 1 OFFSET ' . (date('Ymd') % $total) . ';';
Alix Axel
Gnutt's solution is much more elegant!
Alix Axel
But it's not working... or I'm doing something wrong...
Izumi
A: 

I think you'll need to update the random picked record with "today" field = 1..

Something like this:

// ------------
// Run this 3 commands once a day

// Reset all records
mysql_query("UPDATE `table` SET `today` = 0");

// Pick one
$sql = mysql_query("SELECT `id` FROM `table` ORDER BY RAND() LIMIT 1");
$id = mysql_result($sql, 0, 'id');

// Update the record
mysql_query("UPDATE `table` SET `today` = 1 WHERE `id` = {$id}");

// ------------

// Now you can find again your "random found record":
$query = mysql_query("SELECT * FROM `table` WHERE `today` = 1");
TiuTalk
Too complicated... eh?
TiuTalk
I just don't understand what do you mean by 'running them once a day'... and won't this delete my table? or it creates a new table called 'today'? I'm sorry... I just don't understand... *sighs and looks down*
Izumi
+6  A: 

If you set the SEED for the rand to an integer value that changes daily, that would solve your problem

$query = "SELECT * FROM table ORDER BY rand(" . date("Ymd") . ") LIMIT 1";

Would do the trick.

Gnutt
+1 Dude, I had no idea `RAND()` accepted arguments, this is a brilliant idea!
Alix Axel
@Izumi: Try `$query = "SELECT * FROM table ORDER BY rand(" . date('Ymd') . ") LIMIT 1;";`
Alix Axel
Keep in mind that the `ORDER BY RAND()` is *very* expensive.
Jacco
What do you mean by 'expensive' ?
Izumi
@Gnutt: BTW, welcome to StackOverflow! Keep it up. =)
Alix Axel
by expensive Jacco means, it takes more power from your system than other, perhaps leener approaches.
Gnutt
You learn something new every day...
Martin Bean
Can anyone explain to me why the codes get broken and it says that the fetch is not working properly...
Izumi
Do an echo $query, and print out the responese.. And we'll take it from there ;)
Gnutt
A: 

I'm trying this:

$query = "SELECT * FROM table ORDER BY rand(" . date("Ymd") . ") LIMIT 1";

But I get the following error: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource. This is the part that gets broken:

$results = mysql_query($query); 

while($line = mysql_fetch_assoc($results)) 
Izumi
A: 

I'd suggest caching with APC or memcached or Zend_Cache, e.g. something like this

$dailyPick = '';
$cacheKey = 'dailyPick'. date('dmY');
if($cache->has($cacheKey)) {
    $dailyPick = $cache->get($cacheKey);
} else {
    $dailyPick = $db->query(/* your query */);
    $cache->save($cacheKey, $dailyPick);
}

This way you don't have to hit the db at all if the daily pick was already fetched once and you also do not need a cron job.

Note that is example code. You have to adjust it to work with the API of your cache backend. You cannot copy and paste the code and expect it to work. This is just to illustrate how the program flow should look like.

Gordon
Well, whatever I do, I still get the error that the HAS() function is used on a non-object.
Izumi
Because it is **example** code. You have to setup the cache and the database yourself. You cannot expect us to spoonfed you the entire working code for your application. We can help, but we won't write your application.
Gordon
Well, I'm sorry, but I'm a newbie in php and I have no idea how to set up a cache.
Izumi
Nothing wrong with being a newbie, but some individual initiative is appreciated. Check the links I gave in my answer to see how caching works. Or, if this is too advanced for you now (which is perfectly fine) don't use a cache but one of the other answers.
Gordon
I do think it's too advanced for me... And I already tried the other suggestions as well... I have no idea how to set up a cron job, and the other suggestion with editing the random's seed I'm getting the error that I posted earlier...
Izumi
But you are aware that all of the other answers also do not contain ready to use code snippets, right? The error message you posted for one of the other questions suggested there was no database connection setup. No offense, but why not first read through http://www.tuxradar.com/practicalphp and some of the articles at http://articles.sitepoint.com/category/php-tutorials to learn the basics?
Gordon
No offense taken, but there is a database connection settup. If I use the rand() without any arguments it works, the moment I add the seed rand(" . date("Ymd") . ") - it dies.
Izumi
if you do an echo of the $query what is the output for that?
Gnutt
it echoes the query: SELECT * FROM td_table ORDER BY rand(\' . date("Ymd") . \') LIMIT 1;
Izumi
A: 

So... it should look like this, right? (I mean, choosing the daily random pick?)

$dailyPick = 'SELECT * FROM table ORDER BY rand() LIMIT 1'; 

$cacheKey = 'dailyPick'. date('dmY'); 
if($cache->has($cacheKey)) { 
    $dailyPick = $cache->get($cacheKey); 
} else { 
    // hit database 
    $dailyPick = $cache->save($cacheKey); 
} 
Izumi
@Izumi This is not a discussion board. Please do not open Answers in which you pose additional questions, but edit your initial question if you want to provide more details. Else, this will be pure chaos.
Gordon
okay, I'm sorry
Izumi
And no. It should not look like this. You have to substitute the part where I wrote `// hit database` with an actual db query and then save the result to the cache. I've updated the example.
Gordon