0

表 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 差异(因为在 10:14:44 => 第 4 行和第 3 行之间,速度为 4)+( sum) 第 6 行 - 第 8 行之间的 LogDate 差异。我怀疑它是否正确。我如何在 mysql 查询中计算它。谢谢你。

4

3 回答 3

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中的示例。

于 2013-04-30T07:23:58.773 回答
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

于 2013-04-30T05:35:51.993 回答
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 秒。

于 2013-05-01T04:29:07.127 回答