在MySQL 5.7中,有一个名为ST_Distance_Sphere
的函数可用于查找半径范围内的点,例如:
CREATE TABLE `places` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(256) DEFAULT NULL,
`coordinates` point DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Eiffel Tower", POINT(48.858271, 2.293795));
INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Pere Lachaise", POINT(48.861131, 2.394683));
INSERT INTO `places` ( `name`, `coordinates`)
VALUES ("Brooklyn", POINT(40.711089, -73.948391));
如果我们要查看距巴黎市中心的卢浮宫不到10公里的所有点,则可以执行以下操作:
SELECT name FROM places
WHERE ST_Distance_Sphere(coordinates, POINT(48.861105, 2.335337)) < 10000
但是MariaDB 10.1+中不支持此类功能
如何在MariaDB中重新创建相同的函数或重新创建相同的查询。以下文章显示了一种重新创建相同功能FUNCTION ST_Distance_Sphere does not exist in MariaDB的方法?
也许是这样吗?
SELECT name FROM places
WHERE ST_Within(
coordinates, ST_Buffer(POINT(48.861105, 2.335337), 10000)
);
任何帮助表示赞赏。
答案 0 :(得分:1)
基于@ adam78和@Rick James的建议 我这样解决了:
CREATE FUNCTION st_distance_sphere(pt1 POINT, pt2 POINT)
RETURNS double(10,2)
RETURN 6371000 * 2 * ASIN(
SQRT(
POWER(SIN((ST_Y(pt2) - ST_Y(pt1)) * pi()/180 / 2), 2) +
COS(ST_Y(pt1) * pi()/180 ) *
COS(ST_Y(pt2) * pi()/180) *
POWER(SIN((ST_X(pt2) - ST_X(pt1)) * pi()/180 / 2), 2)
)
)
答案 1 :(得分:0)
我在http://mysql.rjweb.org/doc.php/find_nearest_in_mysql中提供了一种解决方法-但是,它适用于latitude
和longitude
而不是POINTs
的一对数字列。 (可以从POINT()
中提取这些内容。)
该链接的主要目的是您的“下一个”问题-如何按距离加快过滤速度。它讨论了5种方法。 (您的代码仍然是性能最低的代码。)
答案 2 :(得分:0)
我只是遇到了同样的问题。 使用ST_DISTANCE 链接:https://mariadb.com/kb/en/st_distance/ 简单的例子:
SELECT ST_DISTANCE(POINT(x y),POINT(x1 y1));
返回坐标单位。