简体   繁体   English

mysql 计算返回位置的距离

[英]mysql calculate distance for returnning location

This is not a duplicate of: Find distance between two points using latitude and longitude in mysql这不是重复的: 在 mysql 中使用纬度和经度查找两点之间的距离

I tried the query and it's not working, I get empty data set and 0 as the answer.我尝试了查询,但它不起作用,我得到空数据集和 0 作为答案。

SEE answer, THAT is the solution, I don't know why this question was marked as duplicate from Shadow查看答案,这就是解决方案,我不知道为什么这个问题被标记为来自 Shadow 的重复

i have a table with the following structure:我有一个具有以下结构的表:

table: distance
id int(10) primary key
lat float,
lon float,
time timestamp

i have a android application that ping my server and add a record each time it change position.我有一个 android 应用程序 ping 我的服务器并在每次更改 position 时添加一条记录。

for example例如

id:1, lat:40.753979, lon:-111.881721, time = 1571004620
id:2, lat:40.753979, lon:-111.883721, time = 1571004630
id:3, lat:40.753979, lon:-111.885721, time = 1571004640

I can calculate the total distance if I go one direction:如果我 go 一个方向,我可以计算总距离:

/* in my python script*/
startLat,startLon = select lat,lon from distance where time >= 1571004620 order by time limit 1;
endLat,endLon = select lat,lon from distance where time <= 1571004640 order by time desc limit limit 1;

then i can substract both coordinates, which end up giving me a longitute distance of 0.004000然后我可以减去两个坐标,最终得到0.004000的经度距离

problem:问题:

if i add:如果我添加:

id:4, lat:40.753979, lon:-111.881721, time = 1571004650

then I should get: 0.008000那么我应该得到:0.008000

but i get 0 since position 1 is the same as position 4但我得到 0 因为 position 1 与 position 4 相同

You can take advantage of MySQL spatial support, available since 5.7 to perfom the whole computation within the database.您可以利用从 5.7 开始提供的 MySQL 空间支持在数据库中执行整个计算。 Function ST_Distance_Sphere() can be used to compute distances. Function ST_Distance_Sphere()可用于计算距离。

You actually need a cumulative sum of the distance (this requires window functions, available since MySQL 8.0).您实际上需要距离的累积总和(这需要 window 函数,自 MySQL 8.0 起可用)。

Consider:考虑:

SELECT
    id,
    time,
    SUM(
        CASE WHEN lag_lat IS NULL 
            THEN 0
            ELSE ST_Distance_Sphere(point(lag_lon, lag_lat), point(lon, lat))
        END
    ) OVER (ORDER BY time) cumulative_distance
FROM (
    SELECT
        d.*,
        LAG(lat) OVER(ORDER BY time) lag_lat,
        LAG(lon) OVER(ORDER BY time) lag_lon
    FROM distance d
)  x

Demo on DB Fiddle : DB Fiddle 上的演示

| id  | time       | cumulative_distance |
| --- | ---------- | ------------------- |
| 1   | 1571004620 | 0                   |
| 2   | 1571004630 | 168.37177423236415  |
| 3   | 1571004640 | 336.7435484657999   |
| 4   | 1571004650 | 673.4870969097663   |

In earlier versions of MySQL, you need to emulate window functions:在 MySQL 的早期版本中,您需要模拟 window 函数:

  • LAG() can be replaced with a self- LEFT JOIN with a NOT EXISTS condition and a correlated subquery in the ON condition LAG()可以替换为具有NOT EXISTS条件的自LEFT JOINON条件中的相关子查询

  • variables can emulate the cumulative SUM变量可以模拟累积SUM

Query:询问:

SELECT
    id,
    time,
    @running_distance := @running_distance + CASE
        WHEN lag_lat IS NULL THEN 0
        ELSE ST_Distance_Sphere(point(lag_lon, lag_lat), point(lon, lat))
    END running_distance
FROM (
    SELECT
        d.id,
        d.time,
        d.lat,
        d.lon,
        d_lag.lat lag_lat,
        d_lag.lon lag_lon   
    FROM distance d
    LEFT JOIN distance d_lag
        ON  d_lag.time < d.time
        AND NOT EXISTS (
            SELECT 1 
            FROM distance d1
            WHERE d1.time < d.time AND d1.time > d_lag.time
        )
    ORDER BY d.time
) x
CROSS JOIN (SELECT @running_distance := 0) y

Demo on DB Fiddle : same results as above. DB Fiddle 上的演示:与上述结果相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM