views:

200

answers:

6

What's the best way to select only those rows from the table that have been created in last 7 days?

There are dozens of time and date functions in MySQL and I'm a little bit confused about what's the easiest way to do this.

For the sake of this question, assume that you have a table called "my_table" and it contains a row "created_at" which is a DATETIME.

SELECT * FROM my_table WHERE ...

What would you fill in the WHERE clause?

+7  A: 
...WHERE created_at >= Date_Add(now(), INTERVAL -7 DAY)

This is my preferred way because it's so...clear. But ADDDATE is fine too (and you can use the INTERVAL form with that for clarity as well; its default is days so you see people leaving it off). You don't want to do a calculation on created_at and compare it to now() because that requires the computation on created_at on each row (assuming MySQL doesn't optimise it out), whereas modifying now() and comparing to an unmodified created_at means MySQL does that bit once and uses the result when comparing against rows, not to mention indexes.

T.J. Crowder
Wow, can't believe no one noticed the missing underscore in `Date_Add`. I've ... *added* ... it. ;-)
T.J. Crowder
+1  A: 
 WHERE  ADDDATE(datefield, 7) > NOW();
Byron Whitlock
+3  A: 

...... WHERE created_at >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)

hopefully that will help

Sabeen Malik
+2  A: 
WHERE DATEDIFF(NOW(), created_at) <= 7;

I like it because it reads: "Where the Difference in Date between Now and when it was created is at most 7 (days)." in my own head

Drew
Hey I like this :) It's very simple and clean :)
Richard Knop
@Drew .. i maybe wrong here .. but wont that query first convert all created_at records and match afterwards ? isnt that a overhead then doing the match the other way around?
Sabeen Malik
@Sab: I suspect you're right, especially if `created_at` has an index (and it does, right Richard?). It certainly makes life harder for the optimizer, but would need to benchmark to see whether it overcomes it.
T.J. Crowder
I haven't looked up the function yet, but be careful with simply saying "older than 7 days from now" because if it's 1 in the afternoon, many of these types of functions only return results that are from the last `7 * 24 hours` thus leaving out any records from that first day BEFORE 1 PM. That's why my answer uses `DATE()` around any timestamp references
Anthony
created_at doesn't have index actually because it's not used very much, I use it in a where clause only on a single page.
Richard Knop
@Anthony: According to the docs, it only uses the date portion, so it shouldn't do what you fear it might. That particular wad of SQL is just the cleanest way I can write the code. I'm not sure if it's the best for the optimizer. ^^;;
Drew
+1  A: 
SELECT * FROM my_table
WHERE DATE(created_at) >= SUBDATE(DATE(NOW()), 7)
Anthony
+1  A: 

SELECT * FROM my_table WHERE my_table.datefield > sysdate - 7

erikric