【问题标题】:SQL Work out the average time difference between total rowsSQL 计算总行之间的平均时间差
【发布时间】:2011-05-31 17:36:12
【问题描述】:

我搜索了 SO,似乎找不到适合我的答案的问题。我有一个包含近 200 万行的表,每一行都有一个 MySQL 日期格式的字段。

我想计算出插入行的频率(以秒为单位),因此使用 SQL 查询计算出所有行的日期之间的平均差异。

有什么想法吗?

-- 编辑--

这是我的桌子的样子

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

【问题讨论】:

  • 不确定我是否理解这个问题...window functionselect date - lag(date) over (order by date) ...
  • 我认为你可以使用(max(date)-min(date))/(count(*)-1)。无需计算每行之间的差异。

标签: mysql sql time average


【解决方案1】:

如果您想知道(平均)插入一行的频率,我认为您不需要计算所有差异。您只需将相邻行之间的差异(根据时间戳相邻)相加,然后将结果除以被和数。

公式

((T1-T0) + (T2-T1) + … + (TN-TN-1)) / N

显然可以简化为仅仅

(TN-T0) / 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

现在您可以安全地针对具有单行的表运行查询。

【讨论】:

  • 这会在第一个或最后一个日期是异常值的情况下扭曲结果,例如,第一个日期是 10 年前,而所有其他日期都在去年。相反,通过平均差异,您将获得更准确的图片。
  • @RedFilter:对不起,我没有关注你。你的意思是,最好通过实际遵循((T1 - T0) + (T2 - T1) + ... (Tn - Tn-1)) / N 公式来计算平均值?
  • @RedFilter:我的解决方案实现了该公式的简化(或“简化”,我不确定该术语的正确英文是什么)版本,即(TN - T0) / N)
  • +1 必须选择此答案。这是最简单的方法,它可以快速计算平均时间。
【解决方案2】:

试一试:

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

内部查询将每一行与下一行(按日期)连接起来,并返回它们之间的秒数。然后封装该查询并查询平均秒数。

编辑:如果您的 ID 列是自动递增的并且它们按日期顺序排列,您可以通过加入下一个 ID 行而不是 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:正如 Mikael Eriksson 的精彩评论,您也许可以这样做:

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

使用我的第一个示例中的连接语法,您可以做很多事情来消除非高峰时间或没有新记录的大跨度。

【讨论】:

  • 我在查询仍然持续了 7 分钟后取消了查询...我觉得它可能处于某种无限循环中
  • @tamfeld 你确实说过有大约 200 万条记录......给它时间,它不是无限循环。它必须将大约 200 万条记录与大约 200 万条记录连接起来,计算大约 200 万条日期之间的秒数,然后平均大约 200 万个整数。
【解决方案3】:

试试这个:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多