MySQL - 如何获得具有多个纬度和经度的最近位置?
MySQL - How to get nearest locations with multiple latitudes and longitudes?
我找到了一些很好的建议 here 来查找具有一对单一纬度和经度的最近位置。但是我正在寻找一种有效的方法来找到具有一组(多个)纬度和经度对的最近位置。然后对结果进行分组。我可以将 mysql 中的 UNION 与我在下面编写的查询一起使用。但是我正在寻找没有 UNION 的方法。我的 table (user_locations)
+----+--------+-----------+-----------+-----------------------------+
| id | userid | lat | lng | point |
+----+--------+-----------+-----------+-----------------------------+
| 1 | 18 | 48.204784 | 16.369640 | POINT(16.369640, 48.204784) |
+----+--------+-----------+-----------+-----------------------------+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946, 48.205872) |
+----+--------+-----------+-----------+-----------------------------+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867, 48.205914) |
+----+--------+-----------+-----------+-----------------------------+
单经纬度查询:查找[48.205546, 16.368667]附近的用户
SELECT
name,
( 3959 * acos( cos( radians(48.205546) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians(16.368667)) + sin(radians(48.205546))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我希望将上述查询与一组给定的经纬度一起使用:查找附近的用户:
[[48.205546, 16.368667], [48.205084, 16.369712], [48.205660, 16.367947]]
SELECT
name,
( 3959 * acos( cos( radians($lat1,$lat2,$lat3,$lat4) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians($lng1,$lng2,$lng3,$lng4)) + sin(radians($lat))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我并不是真的在寻找特定的输出,因为结果会被分组,所以距离并不是那么重要。用户 18 可能靠近多个经纬度对。使用 userid 对结果进行分组将仅检索一行 userid:18.
+----+--------+-----------+-----------+-----------------------------+--+
| id | userid | lat | lng | point | |
+----+--------+-----------+-----------+-----------------------------+--+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946, 48.205872) | |
+----+--------+-----------+-----------+-----------------------------+--+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867, 48.205914) | |
+----+--------+-----------+-----------+-----------------------------+--+
集合:[[48.205546, 16.368667], [48.205084, 16.369712], [48.205660, 16.367947]]
骇人听闻的解决方案:
SELECT locations.* FROM user_locations AS locations
WHERE (MBRContains
(
LineString
(
Point (
16.368667 + 10 / ( 111.320 / COS(RADIANS(48.205546))),
48.205546 + 10 / 111.133
),
Point (
16.368667 - 10 / ( 111.320 / COS(RADIANS(48.205546))),
48.205546 - 10 / 111.133
)
),
locations.point
)
OR MBRContains
(
LineString
(
Point (
16.369712 + 10 / ( 111.320 / COS(RADIANS(48.205084))),
48.205084 + 10 / 111.133
),
Point (
16.369712 - 10 / ( 111.320 / COS(RADIANS(48.205084))),
48.205084 - 10 / 111.133
)
),
locations.point
)
OR MBRContains
(
LineString
(
Point (
16.367947 + 10 / ( 111.320 / COS(RADIANS(48.205660))),
48.205660 + 10 / 111.133
),
Point (
16.367947 - 10 / ( 111.320 / COS(RADIANS(48.205660))),
48.205660 - 10 / 111.133
)
),
locations.point
))
查询持续时间:0.109 秒(正常)。
注意:点域有SPATIAL索引
10(千米以内的距离)
16.368667(长)
48.205546(纬度)
我找到了一些很好的建议 here 来查找具有一对单一纬度和经度的最近位置。但是我正在寻找一种有效的方法来找到具有一组(多个)纬度和经度对的最近位置。然后对结果进行分组。我可以将 mysql 中的 UNION 与我在下面编写的查询一起使用。但是我正在寻找没有 UNION 的方法。我的 table (user_locations)
+----+--------+-----------+-----------+-----------------------------+
| id | userid | lat | lng | point |
+----+--------+-----------+-----------+-----------------------------+
| 1 | 18 | 48.204784 | 16.369640 | POINT(16.369640, 48.204784) |
+----+--------+-----------+-----------+-----------------------------+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946, 48.205872) |
+----+--------+-----------+-----------+-----------------------------+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867, 48.205914) |
+----+--------+-----------+-----------+-----------------------------+
单经纬度查询:查找[48.205546, 16.368667]附近的用户
SELECT
name,
( 3959 * acos( cos( radians(48.205546) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians(16.368667)) + sin(radians(48.205546))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我希望将上述查询与一组给定的经纬度一起使用:查找附近的用户: [[48.205546, 16.368667], [48.205084, 16.369712], [48.205660, 16.367947]]
SELECT
name,
( 3959 * acos( cos( radians($lat1,$lat2,$lat3,$lat4) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians($lng1,$lng2,$lng3,$lng4)) + sin(radians($lat))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我并不是真的在寻找特定的输出,因为结果会被分组,所以距离并不是那么重要。用户 18 可能靠近多个经纬度对。使用 userid 对结果进行分组将仅检索一行 userid:18.
+----+--------+-----------+-----------+-----------------------------+--+
| id | userid | lat | lng | point | |
+----+--------+-----------+-----------+-----------------------------+--+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946, 48.205872) | |
+----+--------+-----------+-----------+-----------------------------+--+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867, 48.205914) | |
+----+--------+-----------+-----------+-----------------------------+--+
集合:[[48.205546, 16.368667], [48.205084, 16.369712], [48.205660, 16.367947]]
骇人听闻的解决方案:
SELECT locations.* FROM user_locations AS locations
WHERE (MBRContains
(
LineString
(
Point (
16.368667 + 10 / ( 111.320 / COS(RADIANS(48.205546))),
48.205546 + 10 / 111.133
),
Point (
16.368667 - 10 / ( 111.320 / COS(RADIANS(48.205546))),
48.205546 - 10 / 111.133
)
),
locations.point
)
OR MBRContains
(
LineString
(
Point (
16.369712 + 10 / ( 111.320 / COS(RADIANS(48.205084))),
48.205084 + 10 / 111.133
),
Point (
16.369712 - 10 / ( 111.320 / COS(RADIANS(48.205084))),
48.205084 - 10 / 111.133
)
),
locations.point
)
OR MBRContains
(
LineString
(
Point (
16.367947 + 10 / ( 111.320 / COS(RADIANS(48.205660))),
48.205660 + 10 / 111.133
),
Point (
16.367947 - 10 / ( 111.320 / COS(RADIANS(48.205660))),
48.205660 - 10 / 111.133
)
),
locations.point
))
查询持续时间:0.109 秒(正常)。
注意:点域有SPATIAL索引
10(千米以内的距离)
16.368667(长)
48.205546(纬度)