使用 st_distance 在 mysql 中按距离对用户进行排序

Sorting users by distance in mysql using st_distance

我已经阅读了一些这方面的资料,但几乎没有任何关于使用积分和 mysql 中的 st_distance 函数来完成它的信息。我想这是有道理的,因为根据 http://bugs.mysql.com/bug.php?id=70494 it wasn't even documented until halfway through last year. Almost every solution I've seen instead uses separate long and lat columns, and then puts them into the haversine formula like this: sorting distance in MySQL PHP 这似乎是一种非常混乱的方法,尽管由于存在几何数据类型和空间函数。

我的 table 到目前为止是:

用户名 - varchar

位置 - 点 (1 1) 或类似的东西

我想选择一个用户,然后显示离他们最近的 10 个左右的用户。是否可以完全通过 SQL 使用点和 st_distance 函数来完成此操作,还是我必须进行一些更改并改用半正弦公式?

Is it possible to do this entirely through SQL using points and the st_distance function, or will I have to make some changes and use the haversine formula instead?

Geometry Class 中所述:

Geometry is the root class of the hierarchy. It is a noninstantiable class but has a number of properties, described in the following list, that are common to all geometry values created from any of the Geometry subclasses.

[ deletia ]

All calculations are done assuming Euclidean (planar) geometry.

[ deletia ]

For example, in different coordinate systems, the distance between two objects may differ even when objects have the same coordinates, because the distance on the planar coordinate system and the distance on the geocentric system (coordinates on the Earth's surface) are different things.

因此 MySQL 的空间扩展(包括其 ST_Distance() function) cannot be used to calculate geodesics such as great-circle distance, which is what you are after. You will, as you infer, have to use a formula such as Haversine

Google 开发者网站上有一个很好的教程:Creating a Store Locator with PHP, MySQL & Google Maps

CREATE FUNCTION fnDistanceMiles(lat1 DECIMAL(12, 7),
                                lon1 DECIMAL(12, 7),
                                lat2 DECIMAL(12, 7),
                                lon2 DECIMAL(12, 7))
RETURNS DECIMAL(16, 8)
BEGIN

DECLARE DISTANCE DECIMAL(11, 4) DEFAULT 0;

SELECT 69.04117454 *
       DEGREES(ACOS(LEAST(COS(RADIANS(lat1))
                          * COS(RADIANS(lat2))
                          * COS(RADIANS(lon1 - lon2))
                          + SIN(RADIANS(lat1))
                          * SIN(RADIANS(lat2)), 1.0)))
INTO DISTANCE;

RETURN DISTANCE;

END;

DELIMITER ;