Как получить данные из Mysql за дни, по которым нет статистики

StackOverflow https://stackoverflow.com/questions/614739

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top