Как вернуть данные из Mysql за дни, которые не имеют статистики - PullRequest
2 голосов
/ 05 марта 2009

Я хочу получить количество регистраций за период времени (скажем, за неделю), что не так сложно сделать, но мне было интересно, возможно ли в 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 имеет встроенную функциональность.

Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 05 марта 2009

Нет, но одним из обходных путей было бы создание таблицы из одного столбца с первичным ключом даты, предварительно загруженным датами для каждого дня. У вас были бы даты от самой ранней отправной точки до далекого будущего.

Теперь вы можете ПОДКЛЮЧИТЬ свои статистические данные к ним - тогда вы получите нулевые значения для тех дней без данных. Если вы действительно хотите ноль, а не ноль, используйте IFNULL (colname, 0)

1 голос
/ 05 марта 2009

Благодаря Полу Диксону я нашел решение. Все, кто интересуется, как я решил эту проблему, читают:

Сначала создайте хранимую процедуру, которую я нашел где-то, чтобы заполнить таблицу всеми датами этого года.

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

И мы закончили.

Спасибо всем за быстрые ответы и решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...