求和多行日期差异Mysql

时间:2013-04-30 05:10:30

标签: mysql sql

表car_log

 Speed  LogDate
 5      2013-04-30 10:10:09 ->row1
 6      2013-04-30 10:12:15 ->row2
 4      2013-04-30 10:13:44 ->row3
 17     2013-04-30 10:15:32 ->row4
 22     2013-04-30 10:18:19 ->row5
 3      2013-04-30 10:22:33 ->row6
 4      2013-04-30 10:24:14 ->row7
 15     2013-04-30 10:26:59 ->row8
 2      2013-04-30 10:29:19 ->row9

我想知道这辆车的速度在10以下。 在我看来,我将计算第1行 - 第4行之间的LogDate差异(因为在第14行和第3行之间的10:14:44 =>,速度是4)+(和)第6行之间的LogDate差异 - 第8行。我怀疑是对还是不对。 我如何在mysql查询中计算它。谢谢。

3 个答案:

答案 0 :(得分:2)

对于每一行,找到具有更高(稍后)LogDate的第一行。如果此行中的速度小于10,则计算此行的日期与下一行的日期之间的日期差异,否则输入0.

一个查询,它会给出以这种方式计算的值列表,如下所示:

SELECT ( SELECT IF( c1.speed <10, unix_timestamp( c2.LogDate ) - unix_timestamp( c1.logdate ) , 0 )
           FROM car_log c2
           WHERE c2.LogDate > c1.LogDate
           LIMIT 1
       ) AS seconds_below_10
FROM car_log c1

现在只需要总结一下:

SELECT sum( seconds_below_10) FROM 
( SELECT ( SELECT IF( c1.speed <10, unix_timestamp( c2.LogDate ) - unix_timestamp( c1.logdate ) , 0 )
           FROM car_log c2
           WHERE c2.LogDate > c1.LogDate
           LIMIT 1
          ) AS seconds_below_10
  FROM car_log c1 ) seconds_between_logs

关于添加CarId的评论后更新:

如果您有超过1辆车,则需要在依赖子查询中添加一个WHERE条件(我们希望下一个日志用于该确切的汽车,而不仅仅是任何下一个日志)并按CarId对整个行集进行分组,可能会将所述CarId添加到选择也显示它。

SELECT sbl.carId, sum( sbl.seconds_below_10 ) as `seconds_with_speed_less_than_10` FROM
( SELECT c1.carId, 
         ( SELECT IF( c1.speed <10, unix_timestamp( c2.LogDate ) - unix_timestamp( c1.logdate ) , 0 )
           FROM car_log c2
           WHERE c2.LogDate > c1.LogDate AND c2.carId = c1.carId
           LIMIT 1 ) AS seconds_below_10
  FROM car_log c1 ) sbl
GROUP BY sbl.carId

请参阅Sqlfiddle上的示例。

答案 1 :(得分:0)

如果“LogDate”列的类型是MySQL DATETIME类型,则可以使用select语句中的timestampdiff()函数来获取时间戳之间的差异。 timestampdiff函数记录在手册中:  http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_timestampdiff

您需要将查询分解为子查询,然后使用TIMESTAMPDIFF函数。

该函数有三个参数,即你想要结果的单位(例如SECOND,MINUTE,DAY等),然后是Value2,最后是Value1。

要获得速度小于10的LogDate的最大值,请使用:

select MAX(LogDate) from <yourtable> where Speed<10

要获得速度小于10的LogDate的最小值,请使用:

select MIN(LogDate) from <yourtable> where Speed<10

现在,使用TIMESTAMPDIFF函数将它们组合成一个查询:

select TIMESTAMPDIFF(SECOND, (select MAX(LogDate) from <yourtable> where Speed<10, (select MIN(LogDate) from <yourtable> where Speed<10)));

如果LogDate属于不同类型,则还有其他日期/时间差异函数来处理这些类型之间的数学运算。您只需要将“TIMESTAMPDIFF”更改为列类型的正确函数。

其他参考:http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html

答案 2 :(得分:0)

试试这个SQL:

;with data as (
  select * 
  from (  values
    ( 5, convert(datetime,'2013-04-30 10:10:09') ),
    ( 6, convert(datetime,'2013-04-30 10:12:15') ),
    ( 4, convert(datetime,'2013-04-30 10:13:44') ),
    (17, convert(datetime,'2013-04-30 10:15:32') ),
    (22, convert(datetime,'2013-04-30 10:18:19') ),
    ( 3, convert(datetime,'2013-04-30 10:22:33') ),
    ( 4, convert(datetime,'2013-04-30 10:24:14') ),
    (15, convert(datetime,'2013-04-30 10:26:59') ),
    ( 2, convert(datetime,'2013-04-30 10:29:19') )
  ) data(speed,logDate)
) 
, durations as (
select 
    duration = case when speed<=10 
                    then datediff(ss, logDate, endDate)
                    else 0
                    end
from (
  select 
    t1.speed, t1.logDate, endDate = (
      select top 1 logDate 
      from data
      where data.logDate > t1.logDate
    )
  from data t1
) T
where endDate is not null
) 
select TotalDuration = sum(duration)
from durations

从提供的样本数据计算589秒。

相关问题