簡體   English   中英

mysql 計算返回位置的距離

[英]mysql calculate distance for returnning location

這不是重復的: 在 mysql 中使用緯度和經度查找兩點之間的距離

我嘗試了查詢,但它不起作用,我得到空數據集和 0 作為答案。

查看答案,這就是解決方案,我不知道為什么這個問題被標記為來自 Shadow 的重復

我有一個具有以下結構的表:

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

我有一個 android 應用程序 ping 我的服務器並在每次更改 position 時添加一條記錄。

例如

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

如果我 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;

然后我可以減去兩個坐標,最終得到0.004000的經度距離

問題:

如果我添加:

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

那么我應該得到:0.008000

但我得到 0 因為 position 1 與 position 4 相同

您可以利用從 5.7 開始提供的 MySQL 空間支持在數據庫中執行整個計算。 Function ST_Distance_Sphere()可用於計算距離。

您實際上需要距離的累積總和(這需要 window 函數,自 MySQL 8.0 起可用)。

考慮:

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

DB Fiddle 上的演示

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

在 MySQL 的早期版本中,您需要模擬 window 函數:

  • LAG()可以替換為具有NOT EXISTS條件的自LEFT JOINON條件中的相關子查詢

  • 變量可以模擬累積SUM

詢問:

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

DB Fiddle 上的演示:與上述結果相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM