Select 个附近有东西的城镇
Select towns that have nearby things
我有 2 个表格,如下面的示例,towns
和 things
,并且需要获取一个城镇列表,这些城镇附近有距离该城镇 x
距离内的事物记录。纬度和经度将用于计算距离。
我查看了其他一些问题,并设法从 things
获取了单个指定城镇的记录,但想不出如何获取附近有 [=13] 的所有城镇的列表=] 比 x
距离更近。
能够根据 x
距离内附近事物的数量对生成的城镇进行排序将是一个奖励。
TOWNS
+--------+----------+---------+---------+
| townId | townName | townLat | townLng |
+--------+----------+---------+---------+
| 1 | town a | 1.5 | 1.9 |
| 2 | town b | 1.4 | 3.8 |
| 3 | town c | 2.3 | 2.7 |
| 4 | town d | 3.2 | 1.6 |
| ... | ... | ... | ... |
+--------+----------+---------+---------+
THINGS
+---------+-----------+----------+----------+
| thingId | thingName | thingLat | thingLng |
+---------+-----------+----------+----------+
| 1 | thing a | 2.1 | 3.1 |
| 2 | thing b | 1.1 | 2.3 |
| 3 | thing c | 3.2 | 0.2 |
| 4 | thing d | 1.3 | 1.1 |
| ... | ... | ... | ... |
+---------+-----------+----------+----------+
提前致谢
你可以做一个CROSS JOIN
得到所有可能的城镇和事物的组合,然后计算每个城镇和事物之间的Haversine距离。我使用 SELECT DISTINCT
来确保一个城镇在结果集中只列出一次。
SELECT DISTINCT TOWNS.townName FROM
TOWNS CROSS JOIN THINGS
WHERE 3959 * acos(
cos(radians( TOWNS.townLat ))
* cos(radians( THINGS.thingLat ))
* cos(radians( TOWNS.townLng ) - radians( THINGS.thingLng ))
+ sin(radians( TOWNS.townLat ))
* sin(radians( THINGS.thingLat ))
) < x
我使用的公式是 x
英里(地球的平均半径是 3959 英里)。
我有 2 个表格,如下面的示例,towns
和 things
,并且需要获取一个城镇列表,这些城镇附近有距离该城镇 x
距离内的事物记录。纬度和经度将用于计算距离。
我查看了其他一些问题,并设法从 things
获取了单个指定城镇的记录,但想不出如何获取附近有 [=13] 的所有城镇的列表=] 比 x
距离更近。
能够根据 x
距离内附近事物的数量对生成的城镇进行排序将是一个奖励。
TOWNS
+--------+----------+---------+---------+
| townId | townName | townLat | townLng |
+--------+----------+---------+---------+
| 1 | town a | 1.5 | 1.9 |
| 2 | town b | 1.4 | 3.8 |
| 3 | town c | 2.3 | 2.7 |
| 4 | town d | 3.2 | 1.6 |
| ... | ... | ... | ... |
+--------+----------+---------+---------+
THINGS
+---------+-----------+----------+----------+
| thingId | thingName | thingLat | thingLng |
+---------+-----------+----------+----------+
| 1 | thing a | 2.1 | 3.1 |
| 2 | thing b | 1.1 | 2.3 |
| 3 | thing c | 3.2 | 0.2 |
| 4 | thing d | 1.3 | 1.1 |
| ... | ... | ... | ... |
+---------+-----------+----------+----------+
提前致谢
你可以做一个CROSS JOIN
得到所有可能的城镇和事物的组合,然后计算每个城镇和事物之间的Haversine距离。我使用 SELECT DISTINCT
来确保一个城镇在结果集中只列出一次。
SELECT DISTINCT TOWNS.townName FROM
TOWNS CROSS JOIN THINGS
WHERE 3959 * acos(
cos(radians( TOWNS.townLat ))
* cos(radians( THINGS.thingLat ))
* cos(radians( TOWNS.townLng ) - radians( THINGS.thingLng ))
+ sin(radians( TOWNS.townLat ))
* sin(radians( THINGS.thingLat ))
) < x
我使用的公式是 x
英里(地球的平均半径是 3959 英里)。