I have the following schema.
Table votes
+------------------+--------------+------+-----+---------------------+----------------+
| Field |
MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -
Create a table that only holds incrementing numbers - easy to do using an auto_increment:
DROP TABLE IF EXISTS `example`.`numbers`;
CREATE TABLE `example`.`numbers` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Populate the table using:
INSERT INTO NUMBERS
(id)
VALUES
(NULL)
...for as many values as you need.
Use DATE_ADD to construct a list of dates, increasing the days based on the NUMBERS.id value. Replace "2010-01-01" and "2010-01-02" with your respective start and end dates (but use the same format, YYYY-MM-DD HH:MM:SS). In this example, I subtracted the NUMBERS.id value from the CURRENT_DATE to get a list of sequential date values for the last week -
SELECT x.dt
FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
FROM numbers n
WHERE n.id <= 7 ) x
LEFT JOIN onto your table of data based on the datetime portion.
SELECT x.dt,
COUNT(v.aid) AS num
FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
FROM numbers n
WHERE n.id <= 7 ) x
LEFT JOIN VOTES v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)
GROUP BY x.dt
ORDER BY x.dt
Simple - dates can be generated based on the number, like in the example I provided. It also means using a single table, vs say one per data type.
SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,
COUNT(v.aid)
FROM VOTES v
WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
AND CURRENT_DATE
GROUP BY DATE(FROM_UNIXTIME(v.timestamp))
might want to try converting your varchar(20) to a DATETIME, since that is what you are using anyways. But for the last 7 days just do WHERE timestamp > @7DaysAgo. In your explanation you said your using a unix timestamp, so u will need to send the timestamp from now - 7 days. You will also want to change your default to 0, since your sending timestamps you said, not DATETIME values.
SELECT COUNT(*) as votes, aid FROM table WHERE timestamp>@7DaysAgo GROUP BY aid