O MySQL não tem funcionalidade recursiva, então você fica usando o truque da tabela NUMBERS -
-
Crie uma tabela que contenha apenas números incrementais - fácil de fazer usando um 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;
-
Preencha a tabela usando:
INSERT INTO NUMBERS (id) VALUES (NULL)
...para quantos valores você precisar.
-
Use DATE_ADD para construir uma lista de datas, aumentando os dias com base no valor NUMBERS.id. Substitua "2010-01-01" e "2010-01-02" pelas respectivas datas de início e término (mas use o mesmo formato, AAAA-MM-DD HH:MM:SS). Neste exemplo, subtraí o valor NUMBERS.id de CURRENT_DATE para obter uma lista de valores de data sequenciais para a última semana -
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 em sua tabela de dados com base na parte de data e hora.
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
Por que números, não datas?
Simples - as datas podem ser geradas com base no número, como no exemplo que forneci. Isso também significa usar uma única tabela, em vez de uma por tipo de dados.
Anteriormente:
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))