Подтвердить что ты не робот

MySQL: средний интервал между записями

Предположим, что эта таблица:

id    date
----------------
1     2010-12-12
2     2010-12-13
3     2010-12-18
4     2010-12-22
5     2010-12-23

Как найти средние интервалы между этими датами, используя только MySQL-запросы?

Например, вычисление в этой таблице будет

  (
    ( 2010-12-13 - 2010-12-12 )
  + ( 2010-12-18 - 2010-12-13 )
  + ( 2010-12-22 - 2010-12-18 )
  + ( 2010-12-23 - 2010-12-22 )
  ) / 4
----------------------------------
= ( 1 DAY + 5 DAY + 4 DAY + 1 DAY ) / 4
= 2.75 DAY
4b9b3361

Ответ 1

Интуитивно, то, что вы просите, должно быть эквивалентно интервалу между первой и последней датами, деленное на число дат минус 1.

Позвольте мне объяснить более подробно. Представьте, что даты - это точки на линии (+ - даты присутствуют, - отсутствуют даты, первая дата - 12-я, и я изменил последнюю дату на 24 декабря для иллюстрации):

++----+---+-+

Теперь, что вы действительно хотите сделать, равномерно распределите ваши даты между этими строками и найдите, сколько времени между ними:

+--+--+--+--+

Для этого вы просто берете число дней между последним и первым днем, в этом случае 24 - 12 = 12 и делите его на количество интервалов, которые вы должны выделить, в этом случае 4: 12 / 4 = 3.

С запросом MySQL

SELECT DATEDIFF(MAX(dt), MIN(dt)) / (COUNT(dt) - 1) FROM a;

Это работает в этой таблице (с вашими значениями она возвращает 2.75):

CREATE TABLE IF NOT EXISTS `a` (
  `dt` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `a` (`dt`) VALUES
('2010-12-12'),
('2010-12-13'),
('2010-12-18'),
('2010-12-22'),
('2010-12-24');

Ответ 2

Если идентификаторы равномерно увеличиваются без пробелов, присоедините таблицу к себе по id + 1:

SELECT d.id, d.date, n.date, datediff(d.date, n.date)
FROM dates d
JOIN dates n ON(n.id = d.id + 1)

Затем GROUP BY и, если необходимо, среднее значение.

Если идентификаторы не являются однородными, выполните внутренний запрос, чтобы сначала назначить упорядоченные идентификаторы.

Думаю, вам также потребуется добавить подзапрос, чтобы получить общее количество строк.

В качестве альтернативы

Создайте агрегированную функцию, которая отслеживает предыдущую дату, и текущую сумму и количество. Вам все равно нужно выбрать из подзапроса, чтобы заставить упорядочить по дате (на самом деле, я не уверен, что это гарантировано в MySQL).

Подумайте об этом, это гораздо лучший способ сделать это.

И даже проще

Просто отметив, что решение Vegard намного лучше.

Ответ 3

Следующий запрос возвращает правильный результат

SELECT AVG(
        DATEDIFF(i.date, (SELECT MAX(date) 
                          FROM intervals WHERE date < i.date)
                 )
           )
FROM intervals i

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

Ответ 4

Вам нужно сделать самостоятельное соединение и получить различия с помощью функции DATEDIFF и получить среднее значение.