MySQL nie ma funkcji rekurencyjnej, więc pozostaje Ci użycie sztuczki z tabelą NUMBERS -
-
Utwórz tabelę, która zawiera tylko rosnące liczby - łatwo to zrobić za pomocą 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;
-
Wypełnij tabelę za pomocą:
INSERT INTO NUMBERS (id) VALUES (NULL)
...dla tylu wartości, ile potrzebujesz.
-
Użyj DATE_ADD aby skonstruować listę dat, zwiększając liczbę dni na podstawie wartości NUMBERS.id. Zastąp „2010-01-01” i „2010-01-02” odpowiednimi datami rozpoczęcia i zakończenia (ale użyj tego samego formatu, RRRR-MM-DD GG:MM:SS). W tym przykładzie odjąłem wartość NUMBERS.id od CURRENT_DATE, aby uzyskać listę kolejnych wartości dat z ostatniego tygodnia -
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 do tabeli danych na podstawie części daty i godziny.
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
Dlaczego liczby, a nie daty?
Proste - daty mogą być generowane na podstawie liczby, jak w podanym przeze mnie przykładzie. Oznacza to również użycie jednej tabeli, a nie powiedzmy jednej na typ danych.
Wcześniej:
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))