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

For every row, find a first row with higher (later) LogDate. If the speed in this row is less than 10, count date difference between this row's date and next row's date, else put 0.

A query that would give a list of the values counted this way should look like:

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

Now its just a matter of summing it up:

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

Update after comment about adding CarId:

When you have more than 1 car you need to add one more WHERE condition inside dependent subquery (we want next log for that exact car, not just any next log) and group whole rowset by CarId, possibly adding said CarId to the select to show it too.

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

See an example at Sqlfiddle.

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