【问题标题】:How to select from database positions where car has been stopped?如何从汽车已停止的数据库位置中选择?
【发布时间】:2014-04-30 07:47:22
【问题描述】:

我有一个 MySQL 表,其中包含来自汽车 GPS 跟踪器的数据(lat、lng、速度、时间)。我想选择汽车停止(速度 = 0)超过 10 分钟、30 分钟、1 小时等的位置(纬度、经度和时间)。

我的桌子是这样的:

id 纬度 经度 速度 时间 -------------------------------------------------- --------------------- 304 52.388983333333336 17.025338333333334 33.67 2014-03-26 08:00:04 305 52.39029 17.023776666666667 34.65 2014-03-26 08:00:14 306 52.391035 17.021631666666668 32.91 2014-03-26 08:00:24 307 52.39103166666666 17.01917 30.03 2014-03-26 08:00:34 308 52.39089833333333 17.01698 29.33 2014-03-26 08:00:44 309 52.390593333333335 17.01532 9.54 2014-03-26 08:00:54 310 52.39071333333333 17.015056666666666 0 2014-03-26 08:01:04 311 52.39105333333333 17.01499 10.3 2014-03-26 08:01:14 312 52.391485 17.01488 7.82 2014-03-26 08:01:24 313 52.391705 17.014815 0 2014-03-26 08:01:34 314 52.391705 17.014815 0 2014-03-26 08:01:44 315 52.391705 17.014815 0 2014-03-26 08:01:54 316 52.391705 17.014815 0 2014-03-26 08:02:04 317 52.391705 17.014815 0 2014-03-26 08:02:14 318 52.391705 17.014815 0 2014-03-26 08:02:24 319 52.39232333333333 17.014648333333334 7.12 2014-03-26 08:02:34 320 52.392345 17.014635 0 2014-03-26 08:02:44 321 52.392345 17.014635 0 2014-03-26 08:02:54 322 52.392345 17.014635 0 2014-03-26 08:03:04 323 52.392345 17.014635 0 2014-03-26 08:03:15 324 52.392345 17.014635 0 2014-03-26 08:03:25 325 52.392345 17.014635 0 2014-03-26 08:03:35 326 52.392558333333334 17.014471666666665 14.11 2014-03-26 08:03:45 327 52.392316666666666 17.012883333333335 27.47 2014-03-26 08:03:55 328 52.39194333333333 17.010871666666667 28.93 2014-03-26 08:04:05 329 52.39152333333333 17.00893 22.28 2014-03-26 08:04:15 330 52.391575 17.007181666666668 27.01 2014-03-26 08:04:25 331 52.39164 17.00501 26.48 2014-03-26 08:04:35 332 52.39159333333333 17.002895 28.34 2014-03-26 08:04:45 333 52.391641666666665 17.000795 26.39 2014-03-26 08:04:55 334 52.392156666666665 16.999178333333333 16.56 2014-03-26 08:05:05 335 52.39223666666667 16.998796666666667 0 2014-03-26 08:05:15 336 52.39234 16.99819 15.38 2014-03-26 08:05:25 337 52.39261166666667 16.996865 17.1 2014-03-26 08:05:35 338 52.392896666666665 16.995643333333334 20.91 2014-03-26 08:05:45 339 52.39313666666666 16.99468 7.5 2014-03-26 08:05:55 340 52.39331833333333 16.993918333333333 9.1 2014-03-26 08:06:05 341 52.3936 16.992806666666667 16.86 2014-03-26 08:06:15 342 52.393746666666665 16.992065 4.72 2014-03-26 08:06:25

我有一个 MySQL 查询应该这样做,但它会杀死我的数据库。

选择速度、纬度、经度、min(time)作为StartTime,max(time)作为EndTime
从(选择 t.*,
    (选择计数(*)
    从位置 t2
    其中 t2.time 0
    ) 作为 grp
    从位置 t
    ) 吨
    其中时间 >= '$from' AND 时间 = min(time) + 间隔 1 分钟

我正在寻找其他想法如何以速度 0 和空闲时间找到这个位置。

例如:

Speed: 0
StartTime: 2014-03-26 08:01:34
EndTime: 2014-03-26 08:02:24

寻求帮助,有什么想法吗?

【问题讨论】:

  • 您可以添加到此问题中的其他有用信息:表上的索引列表、显示列类型的架构、用于玩弄想法的 SQL Fiddle。
  • 这些位置精确到大约一个原子的宽度!你们波兹纳尼亚人非常精确!

标签: mysql sql database


【解决方案1】:

这会选择空闲超过 10 分钟的职位。内部查询选择所有位置和空闲时间,外部查询按最小空闲时间过滤。对于内部查询,空闲汽车的速度为 0,并且在同一位置至少有 2 行。空闲时间是通过取同一位置的最大和最小时间之间的差来计算的。

SELECT * FROM 
    (SELECT
        latitude,
        longitude,
        TIME_TO_SEC(TIMEDIFF(MAX(time),MIN(time))) idle_time
    FROM positions
    WHERE speed = 0
    GROUP BY latitude, longitude
    HAVING COUNT(*) > 1) t
WHERE idle_time > 600

正如 cmets 中所指出的,上面的查询假设车辆永远不会返回到相同的位置。如果车辆可以返回相同的位置,我们需要确保分组位置是连续的。这在下面的查询中通过验证汽车没有处于每个分组使用的最大和最小时间之间的另一个位置来完成。

未测试

SELECT * FROM 
    (SELECT
        latitude,
        longitude,
        TIME_TO_SEC(TIMEDIFF(max_time,min_time)) idle_time
    FROM (SELECT
        latitude,
        longitude,
        (SELECT MIN(time) 
            FROM positions p2 
            WHERE p2.latitude = p1.latitude
            AND p1.longitude = p2.longitude
            AND NOT EXISTS (SELECT 1 FROM positions p3 
            WHERE p3.time < p1.time AND p3.time > p2.time
            AND (p3.longitude != p2.longitude OR p3.latitude != p2.latitude))
        ) min_time,
        (SELECT MAX(time) 
            FROM positions p2 
            WHERE p2.latitude = p1.latitude
            AND p2.longitude = p1.longitude
            AND NOT EXISTS (SELECT 1 FROM positions p3 
            WHERE p3.time > p1.time AND p3.time < p2.time
            AND (p3.longitude != p2.longitude OR p3.latitude != p2.latitude))
        ) max_time
     FROM positions p1
     WHERE speed = 0) 
    GROUP BY latitude, longitude, min_time, max_time
    HAVING COUNT(*) > 1) t
WHERE idle_time > 600

【讨论】:

  • 如果能稍微解释一下这个方法,而不是代码简介,那就太好了。您至少应该向 OP 教授答案,而不是让他们盲目地复制 + 粘贴。
  • 是否需要包装器?
  • TIME_TO_SEC 函数上不应该有“AS idle_time”吗?即使这样,我也会在此查询中收到错误。
  • @user3476099 我认为错误是由于缺少括号引起的
  • 是的。这几乎是我需要的。我还添加了 StartTime 和 EndTime 。在此之后,我认为还有另一个问题。有时经纬度相差很小,但汽车仍然有速度= 0和怠速。我试图 ROUND(latitude,5), ROUND(longitude,5) 但这也不能解决我的问题。例如 StartTime 06:12:12 EndTime 06:32:15 和 StartTime 06:12:34 EndTime 07:45:12
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
相关资源
最近更新 更多