Как получить данные из Mysql за дни, по которым нет статистики
Вопрос
Я хочу получить количество регистраций за определенный период времени (скажем, за неделю), что не так уж и сложно сделать, но мне было интересно, возможно ли каким-либо образом в MySQL возвращать ноль для дней, в которых нет регистрации.
Пример:ДАННЫЕ:
ID_Profile datCreate 1 2009-02-25 16:45:58 2 2009-02-25 16:45:58 3 2009-02-25 16:45:58 4 2009-02-26 10:23:39 5 2009-02-27 15:07:56 6 2009-03-05 11:57:30
SQL:
SELECT DAY(datCreate) as RegistrationDate, COUNT(ID_Profile) as NumberOfRegistrations FROM tbl_profile WHERE DATE(datCreate) > DATE_SUB(CURDATE(),INTERVAL 9 DAY) GROUP BY RegistrationDate ORDER BY datCreate ASC;
В этом случае результатом будет:
RegistrationDate NumberOfRegistrations 25 3 26 1 27 1 5 1
Очевидно, мне не хватает пары дней между ними.В настоящее время я решаю эту проблему в своем PHP-коде, но мне было интересно, есть ли у MySQL какой-либо способ автоматически возвращать 0 для недостающих дней/строк.Это будет желаемый результат:
RegistrationDate NumberOfRegistrations 25 3 26 1 27 1 28 0 1 0 2 0 3 0 4 0 5 1
Таким образом, мы можем использовать MySQL для решения любых проблем, связанных с количеством дней в месяце, вместо того, чтобы полагаться на PHP-код для расчета количества дней в каждом месяце, поскольку MySQL имеет встроенную функциональность.
заранее спасибо
Решение
Нет, но одним из обходных путей может быть создание таблицы из одного столбца с первичным ключом даты, в которую предварительно загружены даты для каждого дня.У вас будут даты от самой ранней отправной точки до какого-то далекого будущего.
Теперь вы можете LEFT JOIN объединить свои статистические данные с ним - тогда вы получите нули за те дни, когда данных нет.Если вам действительно нужен ноль, а не ноль, используйте IFNULL(имя столбца, 0)
Другие советы
Благодаря Полу Диксону я нашел решение.Кому интересно, как я это решил, читайте дальше:
Сначала создайте хранимую процедуру, которую я где-то нашел, чтобы заполнить таблицу всеми датами этого года.
CREATE Table calendar(dt date not null); CREATE PROCEDURE sp_calendar(IN start_date DATE, IN end_date DATE, OUT result_text TEXT) BEGIN SET @begin = 'INSERT INTO calendar(dt) VALUES '; SET @date = start_date; SET @max = SUBDATE(end_date, INTERVAL 1 DAY); SET @temp = ''; REPEAT SET @temp = concat(@temp, '(''', @date, '''), '); SET @date = ADDDATE(@date, INTERVAL 1 DAY); UNTIL @date > @max END REPEAT; SET @temp = concat(@temp, '(''', @date, ''')'); SET result_text = concat(@begin, @temp); END call sp_calendar('2009-01-01', '2010-01-01', @z); select @z;
Затем измените запрос, чтобы добавить левое соединение:
SELECT DAY(dt) as RegistrationDate, COUNT(ID_Profile) as NumberOfRegistrations FROM calendar LEFT JOIN tbl_profile ON calendar.dt = tbl_profile.datCreate WHERE dt BETWEEN DATE_SUB(CURDATE(),INTERVAL 6 DAY) AND CURDATE() GROUP BY RegistrationDate ORDER BY dt ASC
И мы закончили.
Спасибо всем за быстрые ответы и решение.