So I have a table that contains votes. The relevant columns for this issue being user
and timestamp
.
I need to grab the user's total vote count, and also their votes this month.
I know the queries - I'm not asking for those. I use these at the same time:
Votes this month / Total votes:
SELECT COUNT( 0 ) FROM votes WHERE ( timestamp BETWEEN DATE_FORMAT( NOW( ) ,'%Y-%m-01' ) AND NOW( ) ) AND user = ?;
SELECT COUNT( 0 ) FROM votes WHERE user = ?;
At the moment, my database isn't large enough (or even queried enough) to where performance is an issue. However, that's expected to change shortly. Should I keep the queries separate, or should I:
SELECT COUNT( 0 ) AS totalVotes,
SUM( IF( timestamp BETWEEN DATE_FORMAT( NOW( ) ,'%Y-%m-01' )
AND NOW( ), 1, 0 ) ) AS votesThisMonth
FROM votes WHERE user = ?;
What is the best practice? Are there any tips for querying multiple bits of information from the same table to prevent having to search it twice? Is my combined query even what I should be using?
Thanks!
In MySQL, I would recommend:
SELECT COUNT(*) AS totalVotes,
SUM(EXTRACT(YEAR_MONTH FROM timestamp) = EXTRACT(YEAR_MONTH FROM NOW())) AS votesThisMonth
FROM votes
WHERE user = ?;
An alternative to the above is:
SUM(timestamp >= CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAY)
I strongly discourage you from using strings for dates, unless you really have to. There are multiple ways to get values from the current date that do NOT involves implicitly or explicitly converting a date/time value to a string.
Also, the IF()
is redundant. MySQL allows you to just add up boolean values. Neither is standard SQL, so you might as well use the more concise version.
The COUNT(0)
is jarring to me. Although it works, COUNT(*)
or COUNT(1)
seem simpler.