Данные подсчета MySQL за последние 7 дней
У меня есть следующая схема.
Таблица голосов
+------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------------------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| aid | varchar(10) | NO | | | |
| ip | varchar(100) | NO | | | |
| host | varchar(200) | NO | | | |
| timestamp | varchar(20) | NO | | 0000-00-00 00:00:00 | |
| user | tinytext | NO | | NULL | |
| userid | int(10) | NO | | 0 | |
+------------------+--------------+------+-----+---------------------+----------------+
Здесь я хочу получить счет каждой помощи за день за последние 7 дней с 0 для дат, когда нет голосов за помощь. метка времени - это метка времени Unix.
Любая помощь высоко ценится.
2 ответа
MySQL не имеет рекурсивной функциональности, поэтому вам нужно использовать табличный трюк NUMBERS -
Создайте таблицу, которая содержит только увеличивающиеся числа - это легко сделать с помощью 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;
Заполните таблицу, используя:
INSERT INTO NUMBERS (id) VALUES (NULL)
... столько ценностей, сколько вам нужно.
Используйте DATE_ADD для построения списка дат, увеличивая количество дней на основе значения NUMBERS.id. 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
СЛЕДУЮЩИЙ ПРИСОЕДИНЯЙТЕСЬ к своей таблице данных, основанной на части datetime.
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
Почему цифры, а не даты?
Просто - даты могут быть сгенерированы на основе числа, как в приведенном мной примере. Это также означает использование одной таблицы, скажем, по одной для каждого типа данных.
Ранее:
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))
Возможно, вы захотите попробовать конвертировать ваш varchar(20) в DATETIME, так как это то, что вы используете в любом случае. Но за последние 7 дней просто сделайте ГДЕ отметку времени> @7DaysAgo. В своем объяснении вы сказали, что используете метку времени Unix, поэтому вам нужно будет отправить метку времени с этого момента - 7 дней. Вы также захотите изменить значение по умолчанию на 0, так как вы указали временные метки отправки, а не значения DATETIME.
ВЫБЕРИТЕ COUNT(*) в качестве голосов, помогите ИЗ таблицы, ГДЕ отметка времени>@7DaysAgo GROUP BY help