Накопленное среднее количество записей, созданных для определенного дня недели или диапазона дат - PullRequest
1 голос
/ 30 ноября 2009

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

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

Теперь, вот в чем проблема, у меня нет большого опыта работы с MySql, когда дело доходит до сопоставления совокупной суммы и скользящих средних. Я собрал следующий запрос, который имеет смысл для меня, но он просто блокирует командную консоль. Выполнение этой задачи занимает вечность, и в тестовом образце есть только 80 тыс. Записей.

Итак, учитывая следующую базовую структуру таблицы:

id   | action | date_created
1    | 'merp' | 2007-06-20 17:17:00
2    | 'foo'  | 2007-06-21 09:54:48
3    | 'bar'  | 2007-06-21 12:47:30
... thousands of records ...
3545 | 'stab' | 2007-07-05 11:28:36

Как мне рассчитать среднее количество записей, созданных для каждого дня недели?

day_of_week | average_records_created
1           | 234
2           | 23
3           | 5
4           | 67
5           | 234
6           | 12
7           | 36

У меня следующий запрос, который заставляет меня хотеть убить себя, убить себя, бросив свое тело вниз по шахте лифта ... и на несколько пуль:

SELECT
    DISTINCT(DAYOFWEEK(DATE(t1.datetime_entry))) AS t1.day_of_week,
    AVG((SELECT COUNT(*) FROM VMS_LOGS t2 WHERE DAYOFWEEK(DATE(t2.date_time_entry)) = t1.day_of_week)) AS average_records_created
FROM VMS_LOGS t1
GROUP BY t1.day_of_week;

Halps? Пожалуйста, не заставляй меня снова порезаться. : '(

Ответы [ 3 ]

1 голос
/ 30 ноября 2009

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

Даже с оптимизацией, написанной OMG Ponies (ниже), вы по-прежнему просматриваете примерно такое же количество запросов.

  SELECT x.day_of_week,
         AVG(x.count) 'average_records_created'
    FROM (SELECT DAYOFWEEK(t.datetime_entry) 'day_of_week',
                 COUNT(*) 'count'
            FROM VMS_LOGS t
        GROUP BY DAYOFWEEK(t.datetime_entry)) x
  GROUP BY x.day_of_week
1 голос
/ 30 ноября 2009

Как далеко вы должны пройти при отборе этой информации? Это решение работает до тех пор, пока оно меньше года.

Поскольку день недели и номер недели являются постоянными для записи, создайте сопутствующую таблицу с ID, WeekNumber и DayOfWeek. Всякий раз, когда вы хотите запустить эту статистику, просто сгенерируйте «пропущенные» записи из вашей основной таблицы.

Тогда ваш отчет может быть чем-то вроде:

select
  DayOfWeek
, count(*)/count(distinct(WeekNumber)) as Average
from
  MyCompanionTable
group by
  DayOfWeek

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

1 голос
/ 30 ноября 2009

Я переписал ваш запрос как:

  SELECT x.day_of_week,
         AVG(x.count) 'average_records_created'
    FROM (SELECT DAYOFWEEK(t.datetime_entry) 'day_of_week',
                 COUNT(*) 'count'
            FROM VMS_LOGS t
        GROUP BY DAYOFWEEK(t.datetime_entry)) x
GROUP BY x.day_of_week
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...