SQL рассчитать среднюю разницу во времени между общими строками - PullRequest
3 голосов
/ 31 мая 2011

Я искал вокруг SO и не могу найти вопрос с ответом, который мне подходит. У меня есть таблица с почти 2 миллионами строк, и в каждой строке есть поле в формате MySQL Date.

Я бы хотел выяснить (в секундах), как часто вставлялась строка, поэтому рассчитайте среднюю разницу между датами всех строк в запросе SQL.

Есть идеи?

- РЕДАКТИРОВАТЬ -

Вот как выглядит мой стол

id, name, date (datetime), age, gender

Ответы [ 3 ]

10 голосов
/ 31 мая 2011

Если вы хотите узнать, как часто (в среднем) строка вставлялась, я не думаю, что вам нужно вычислять все различия. Вам нужно только суммировать различия между соседними строками (смежными на основе отметки времени) и делить результат на количество слагаемых.

Формула

((T<sub>1</sub>-T<sub>0</sub>) + (T<sub>2</sub>-T<sub>1</sub>) + … + (T<sub>N</sub>-T<sub>N-1</sub>)) / N

, очевидно, может быть упрощен до

(T<sub>N</sub>-T<sub>0</sub>) / N

Итак, запрос будет выглядеть примерно так:

SELECT TIMESTAMPDIFF(SECOND, MIN(date), MAX(date)) / (COUNT(*) - 1)
FROM atable

Убедитесь, что количество строк больше 1, иначе вы получите ошибку деления на ноль. Тем не менее, если хотите, вы можете предотвратить ошибку с помощью простого трюка:

SELECT
  IFNULL(TIMESTAMPDIFF(SECOND, MIN(date), MAX(date)) / NULLIF(COUNT(*) - 1, 0), 0)
FROM atable

Теперь вы можете безопасно выполнять запрос к таблице с одной строкой.

3 голосов
/ 31 мая 2011

Дайте этому шанс:

select AVG(theDelay) from (

    select TIMESTAMPDIFF(SECOND,a.date, b.date) as theDelay
    from myTable a
    join myTable b on b.date = (select MIN(x.date) 
                                from myTable x 
                                where x.date > a.date)

) p

Внутренний запрос объединяет каждую строку со следующей строкой (по дате) и возвращает количество секунд между ними. Этот запрос затем инкапсулируется и запрашивается для среднего количества секунд.

РЕДАКТИРОВАТЬ: если ваш столбец идентификатора имеет автоинкремент и они расположены в порядке дат, вы можете ускорить его, присоединившись к следующей строке идентификатора, а не к следующей дате MIN.

select AVG(theDelay) from (

    select TIMESTAMPDIFF(SECOND,a.date, b.date) as theDelay
    from myTable a
    join myTable b on b.date = (select MIN(x.id) 
                                from myTable x 
                                where x.id > a.id)

) p

EDIT2: Как блестяще прокомментировал Микаэль Эрикссон, вы можете просто сделать:

select (TIMESTAMPDIFF(SECOND,(MAX(date),MIN(date)) / COUNT(*)) from myTable

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

1 голос
/ 31 мая 2011

Попробуйте это:

select avg(diff) as AverageSecondsBetweenDates
from (
    select TIMESTAMPDIFF(SECOND, t1.MyDate, min(t2.MyDate)) as diff
    from MyTable t1
    inner join MyTable t2 on t2.MyDate > t1.MyDate
    group by t1.MyDate
) a
...