表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查询中计算它。谢谢。
答案 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秒。