2013-04-30 58 views
0

表car_log总和多行的时间差Mysql的

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

+2

你的问题不是很清楚。你需要改进它的描述。 – dmg 2013-04-30 05:18:37

+0

请提供良好的信息。这很混乱。 – Anvesh 2013-04-30 05:27:41

+0

对不起我的英文不好。问题是,我想知道汽车在10速以下运行多久。 – 2013-04-30 06:17:31

回答

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台车,你的东东d在依赖的子查询中添加一个WHERE条件(我们希望下一个日志适用于那辆精确的汽车,而不仅仅是下一个日志),并且可以通过CarId对整个行集合进行分组,可能会将所述CarId添加到select以显示它。

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

+0

非常感谢。它运作良好, – 2013-04-30 08:34:57

+0

又对不起,我是初学者。我如何分组结果,例如,如果在Speed列之前我有列CarId。我想将CarId的结果分组,您能再次告诉我如何解决它Piotrm先生?谢谢。我希望我的问题很清楚。 – 2013-04-30 08:50:02

+0

再次感谢Piotrm先生。你救了我的一天:) – 2013-05-01 01:29:38

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。

要获得LOGDATE最大值在速度低于10使用:

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

要获得LOGDATE的最低值,其中速度小于10使用:

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是一个di不同类型,还有其他日期/时间差异函数来处理这些类型之间的数学。您只需将'TIMESTAMPDIFF'更改为您的列类型的正确功能。

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

+0

问题是当速度大于10并且行存在于中间时(请查看汽车表格内容/行)。使用你的解决方案,我认为结果不准确。 – 2013-04-30 06:23:29

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秒。

+0

如果在我的表中我有大约200.000行数据。作为我的评论中的问题,我希望结果由CarId分组 – 2013-05-01 06:29:29