tags:

views:

33

answers:

2

i have table posts and posts_votes in posts_votes i have id and post_id and vote now i want select from posts where have top votes count in last 1 day using this to set the time

from_unixtime(post_date) >= SUBDATE(NOW(),1)

thanks in advance

+2  A: 

maybe something like this:

SELECT
    posts.*,
    pv.votes
FROM
    posts JOIN
    (
        SELECT post_id, COUNT(*) AS votes FROM posts_votes GROUP BY post_id
    ) AS pv ON posts.id=pv.post_id
WHERE
    posts.post_date >= UNIX_TIMESTAMP()-86400
ORDER BY
    pv.votes DESC;
Ty W
what this mean votes FROM posts_votes GROUP BY posts_votes
moustafa
actually that's a typo, let me edit quickly and I'll explain
Ty W
`UNIX_TIMESTAMP()-86400` doesn't account for daylight savings. It's best to use the built in functions like DATE_ADD, or SUBDATE() as moustafa was using.
Marcus Adams
everything between the parenthesis is a subquery. the `GROUP BY post_id` tells MySQL that you want to group the votes by the post they voted for so that you can `COUNT` the votes for each post. if you run the subquery on your MySQL command line it will be easier to understand what it does.
Ty W
@Marcus: agreed. but +/- an hour occasionally is probably not the end of the world for his apparent purposes and isn't the part he was having trouble with. that line can be replaced with any date_add/subdate/etc expression.
Ty W
+1  A: 

Utilizing the GROUP BY clause allows you to aggregate data on a particular column without resorting to a sub query or derived table.

This query returns all posts, ordered by vote count in descending order:

SELECT p.*
FROM posts p
JOIN posts_votes pv
ON pv.post_id = p.id
WHERE FROM_UNIXTIME(p.post_date) >= SUBDATE(NOW(), 1)
GROUP BY p.id
ORDER BY COUNT(pv.post_id) DESC

If you wanted to limit it to the top ten posts, you could add the LIMIT clause:

SELECT p.*
FROM posts p
JOIN posts_votes pv
ON pv.post_id = p.id
WHERE FROM_UNIXTIME(p.post_date) >= SUBDATE(NOW(), 1)
GROUP BY p.id
ORDER BY COUNT(pv.post_id) DESC
LIMIT 10

MySQL may be able to optimize the date comparison, however, in general, try to perform all of your functions on the constant (the right side) instead of on the column (the left side).

For example, you should change this:

WHERE FROM_UNIXTIME(p.post_date) >= SUBDATE(NOW(), 1)

To this:

WHERE p.post_date >= UNIX_TIMESTAMP(SUBDATE(NOW(), 1))

This way, MySQL doesn't have to run FROM_UNIXTIME() on every row. Again, MySQL may realize this and auto optimize, but it's best practice.

Marcus Adams