Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql query: how to get the number of yes/no votes per day

Tags:

mysql

I have to create a mysql query to get a voting distribution of each day exceeding a particular date, something like this...

    date          yes_votes    no_votes
------------------------------------------
    2010-01-07    21           22
    2010-01-07    2            0

My table is like this..

    post_votes
--------------------------
    id(longint)
    date(timestamp)
    flag(tinyint) // this stores the yes/no votes 1-yes, 2-no

I am stuck at this....

SELECT COUNT(*) AS count, DATE(date) FROM post_votes WHERE date > '2010-07-01' GROUP BY DATE(date)

this gives the total number of votes per day, but not the distribution that I want.

like image 305
vikmalhotra Avatar asked Jun 02 '11 07:06

vikmalhotra


4 Answers

SELECT COUNT(*) AS count
     , DATE(date)
     , SUM(flag = 1) AS yes_votes
     , SUM(flag = 2) AS no_votes
FROM post_votes 
WHERE date > '2010-07-01' 
GROUP BY DATE(date)

This is a trick that works in MySQL, as flag=1 will either be True or False. But True = 1 and False = 0 in MySQL so you can add the 1s and 0s using the SUM() function.

Other solutions with IF or CASE would be better for clarity or if there is any chance you want to move the database to another RDBMS.

Comments not related to the question:

  • It's bad habit to use reserved words like date or count for naming fields or tables.
  • It's also not good to use "date" when you actually store a timestamp. Names should reflect use.
  • For table names it's recommended to use singular (post_vote) and not plural - although many use plural, it gets confusing in the end. Plural is good for some fields or calulated fields, like your yes_votes and no_votes where we have a counting.
like image 108
ypercubeᵀᴹ Avatar answered Nov 14 '22 22:11

ypercubeᵀᴹ


Sum it:

select date(date) as date,
       sum(case when flag = 1 then 1 else 0) as yes,
       sum(case when flag = 2 then 1 else 0) as no
from post_votes
where date > '2010-07-01'
group by date(date)
like image 22
Denis de Bernardy Avatar answered Nov 14 '22 22:11

Denis de Bernardy


you are almost at the solution :)

i would recommend the use of an IF condition in a SUM method like so:

SELECT SUM(IF(flag = 'yes',1,0)) AS yes_count,
       SUM(IF(flag = 'no',1,0)) AS no_count, 
       DATE(date) 
FROM post_votes 
WHERE date > '2010-07-01' 
GROUP BY DATE(date)

this will allow for the function to add 1 to each sum only if the value is equal to yes/no

like image 24
BigFatBaby Avatar answered Nov 14 '22 23:11

BigFatBaby


SELECT DATE(date) as dt,
sum(if(flag=1,1,0)) as yes,
sum(if(flag=2,1,0)) as no
FROM post_votes WHERE date > '2010-07-01' 
GROUP BY dt
like image 23
Nicola Cossu Avatar answered Nov 15 '22 00:11

Nicola Cossu