23

假设这张表:

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
4

4 回答 4

46

直观地说,您所要求的应该等于第一个日期和最后一个日期之间的间隔除以日期数减 1。

让我更彻底地解释一下。想象一下日期是一条线上的点(+日期是否存在,-日期是否缺失,第一个日期是 12 日,为了说明目的,我将最后一个日期更改为 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');
于 2010-11-30T10:17:29.290 回答
3

如果 id 一致地递增而没有间隙,则在 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 和平均。

如果 id 不统一,请先进行内部查询以分配有序 id。

我想您还需要添加一个子查询来获取总行数。

或者

创建一个聚合函数来跟踪前一个日期以及运行总和和计数。您仍然需要从子查询中进行选择以强制按日期排序(实际上,我不确定 MySQL 是否保证了这一点)。

想一想,这是一种更好的方法。

甚至更简单

只是注意到 Vegard 的解决方案要好得多。

于 2010-11-30T09:44:33.873 回答
1

以下查询返回正确结果

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

但它运行一个依赖子查询,在没有索引和大量行的情况下,它可能真的效率低下。

于 2010-11-30T10:29:36.320 回答
0

您需要使用 DATEDIFF 函数进行自我加入并获得差异并获得平均值。

于 2010-11-30T09:40:56.307 回答