【问题标题】:How do I query average time difference with multiple rows?如何查询多行的平均时差?
【发布时间】:2014-10-03 16:27:44
【问题描述】:

我有下表,基本上是扫描日志。

+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| location_id   | int(10) unsigned | YES  | MUL | NULL    |                |
| code          | varchar(255)     | YES  |     | NULL    |                |
| created       | datetime         | YES  |     | NULL    |                |
| last_modified | datetime         | YES  |     | NULL    |                |
+---------------+------------------+------+-----+---------+----------------+

这是一些示例数据的简单示例。 location_id 为 1 为入口,location_id 为 2 为出口。我想知道一个人(代码)从入口到出口的平均时间。

+----+-------------+------+---------------------+---------------+
| id | location_id | code | created             | last_modified |
+----+-------------+------+---------------------+---------------+
| 1  | 1           | 0005 | 2014-10-03 10:01:56 | NULL          |
| 2  | 1           | 0006 | 2014-10-03 10:03:08 | NULL          |
| 3  | 2           | 0005 | 2014-10-03 10:10:16 | NULL          |
| 4  | 2           | 0006 | 2014-10-03 10:10:18 | NULL          |
+----+-------------+------+---------------------+---------------+ 

我不确定我需要为此查询执行哪种联接。有什么想法吗?

【问题讨论】:

  • 代码是唯一的还是会被重复用于另一个进入/退出?
  • 大多数代码每个位置只会使用一次,但有些代码可以多次通过每个位置。

标签: mysql sql time average


【解决方案1】:

我会使用相关子查询来做到这一点。对于带有“1”的每一行,您需要下一行具有相同的“代码”和“2”:

select t.*,
       (select t2.created
        from table t2
        where t2.code = t.code and
              t2.id > t.id and
              t2.location_id = 2 and
        order by t2.id desc
        limit 1
       ) as exitdte
from table t;

然后您可以使用timestampdiff() 之类的东西来获得时间差,并使用avg() 来获得适当的平均值。

出于性能原因,您应该在table(code, location, id, created) 上有一个索引。

【讨论】:

  • +1 因为timestampdiff()AVG DATETIME won't work 上的其他答案...
【解决方案2】:

可能是这样的:(警告,老派 SQL :))

SELECT AVG(b.created - a.created) as average
  FROM (SELECT created FROM table WHERE location_id = (should be a parameter) AND code = '0005') AS a,
       (SELECT created FROM table WHERE location_id = (should be a parameter) AND code = '0006') AS b

【讨论】:

    【解决方案3】:

    我们可以在同一张表上进行自连接以获取每个代码的进入时间和退出时间列表。 这两次的差值可以取平均值。

    这里是 SQL 小提琴:http://www.sqlfiddle.com/#!2/5a4d4

    select t1.code, avg( t1.created - t2.created) average
        from Table1 t1
        Join Table1 t2
            on t1.code = t2.code
            and t1.location_id = 2
            and t2.location_id =1
        group by t1.code
    

    【讨论】:

    • 你应该改进你的答案,而不仅仅是转储几行代码。
    • @slybloty,感谢您的反馈。用 cmets 和 sqlfiddle 更新了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多