数据库有个表,存的地址及其经纬度,想要查询每个地址距当前位置(经纬度)的距离(单位:米)并根据距离进行排序。

创建表store

CREATE TABLE `store` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`phone` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`province_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`city_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`region_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`address` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,`lng` decimal(10,6) unsigned DEFAULT NULL COMMENT '经度',`lat` decimal(10,6) unsigned DEFAULT NULL COMMENT '纬度',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3540 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;//插入数据
INSERT INTO `store` VALUES (2597, '芦庄店', '10080109', '131-1508-9880', '320000', '320200', '320211', '江苏无锡市滨湖区芦庄路58-1号', 120.313392, 31.529345);
INSERT INTO `store` VALUES (2598, '莱西商业街店', '10220040', '15921422440', '370000', '370200', '370285', '山东青岛市莱西市 山东省青岛市莱西市商业街', 120.528315, 36.865844);
INSERT INTO `store` VALUES (2599, '椒江康平路店', '10170163', '。', '330000', '331000', '331002', '浙江台州市椒江区康平路229号', 121.424017, 28.656769);
INSERT INTO `store` VALUES (2600, '长兴利时广场店', '10170161', '。', '330000', '330500', '330522', '浙江湖州市长兴县中央大道与长洲路交叉口的利时广场', 119.925811, 31.026153);
INSERT INTO `store` VALUES (2601, '豫园人民店', '10010321', '132-6252-0090', '310000', '310100', '310101', '上海市上海市黄浦区上海市黄浦区人民路399号NEO商厦1层03单元', 121.498505, 31.234871);
INSERT INTO `store` VALUES (2602, '宝杨宝龙店', '10010331', '18818292910', '310000', '310100', '310113', '上海市上海市宝山区上海市宝山区同济路669弄8号', 121.488406, 31.400972);
INSERT INTO `store` VALUES (2603, '浦江万达店', '10010333', '54386385', '310000', '310100', '310112', '上海市上海市闵行区永跃路360号', 121.518080, 31.033337);
INSERT INTO `store` VALUES (2604, '奉贤海泉店', '10010335', '021-37596218', '310000', '310100', '310120', '上海市上海市奉贤区上海市奉贤区海泉路575号1层', 121.517148, 30.848402);
INSERT INTO `store` VALUES (2605, '青浦绿地滨纷城店', '10010336', '未开业', '310000', '310100', '310118', '上海市上海市青浦区上海市青浦区外青松公路5999弄B1层B1-03-a', 121.131746, 31.165160);
INSERT INTO `store` VALUES (2606, '万嘉店', '10010337', '未开业', '310000', '310100', '310115', '上海市上海市浦东新区上海市浦东新区行德路86、92、96、100号万嘉商业广场一层33室', 121.617300, 31.299490);
INSERT INTO `store` VALUES (2607, '益江路店', '10010340', '未开业', '310000', '310100', '310115', '上海市上海市浦东新区上海市浦东新区益江路127号1楼-5室', 121.630805, 31.209385);
INSERT INTO `store` VALUES (2608, '青浦苏杭时代店', '10010342', '187-0214-7370', '310000', '310100', '310118', '上海市上海市青浦区上海市青浦区华新镇华腾公路558号苏杭时代华新店一层1F-01', 121.234843, 31.243568);
INSERT INTO `store` VALUES (2609, '玫瑰天街店', '10240011', '18828020857', '500000', '500100', '500112', '重庆市 重庆市渝北区重庆市北部新区金洲大道42号4幢1-115号', 106.552117, 29.649191);
INSERT INTO `store` VALUES (2610, '金贸时代店', '10240013', '13983980552', '500000', '500100', '500112', '重庆市 重庆市渝北区重庆市北部新区栖霞16号3幢1-3商铺', 106.572516, 29.644757);

注意:上述数据经纬度不一定准确,不过并不影响SQL测试

方法一:

SELECT*,ROUND(6378.138 * 2 * ASIN(SQRT(POW( SIN(( 31.163973 * PI()/ 180-lat * PI()/ 180 )/ 2 ), 2 )+ COS( 31.163973 * PI()/ 180 )* COS( lat * PI()/ 180 )* POW( SIN(( 121.404032 * PI()/ 180-lng * PI()/ 180 )/ 2 ), 2 ))) * 1000 ) AS dis
FROMstore
ORDER BYdis ASC;#简化SELECT*,ROUND(6378.138 * 2 * ASIN(SQRT(POW( SIN(( 31.163973 - lat ) * PI()/ 360 ), 2 ) + COS( 31.163973 * PI() / 180 ) * COS( lat * PI() / 180 ) * POW( SIN(( 121.404032 - lng ) * PI() / 360 ), 2 ))) * 1000 ) AS dis
FROMstore
ORDER BYdis ASC;


dis单位为m,如果想变为km的话可以将SQL语句中的 *1000去掉

方法二:

采用的这种方法,实现起来更简单,当然存储引擎可以是InnoDB。

需要用到st_distance函数

POINT():从坐标构造点
ST_DISTANCE():一个几何体与另一个几何体的距离,计算的结果单位是度,需要乘6371000*π/180=111195是将值转化为米。

MySQL其实在很早就提供了这种存储经纬度及相关运算的功能,这种数据类型叫做空间数据类型,而对应的索引被称为空间索引,但由于MySQL之前的版本对InnoDB支持的并不是太好,所以使用的并不多。不过MySQL5.6和MySQL5.7对此进行了优化,添加了st_distance等相关函数来支持经纬度相关的计算。

地球半径6371km

SELECT*,( st_distance ( point ( lng, lat ), point ( 121.404032, 31.163973 )) * 111195 ) AS dis
FROMstore
ORDER BYdis ASC;


dis单位是米

处理dis为整型

SELECT*,CAST(( st_distance ( point ( lng, lat ), point ( 121.404032, 31.163973 )) * 111195 ) AS DECIMAL(10,0)) AS dis
FROMstore
ORDER BYdis ASC;

总结

对比两种方法,‘方法一’查询效率更高一些。但是经过地图实测验证,发现‘方法二’计算的距离精度更高。

根据经纬度查询距离并按距离进行排序相关推荐

  1. Mysql实现根据经纬度查询周围的商家,并按距离进行排序

    今天要说的是如何在Mysql中实现根据已知的经纬度查询周围的商家(或者是别的带有经纬度字段的表)并且根据距离的远近来进行排序! 废话就不多说了,直奔主题~ 首先有这么个商城表 lng代表经度,lat代 ...

  2. mysql根据经纬度查询范围内数据,并根据距离排序

    最近接到一个新需求,要根据经纬度查询指定范围内的数据,并且根据距离进行排序,网上找了找相关实现方法,记录一下. java代码如下 public final class DistanceUtils {/ ...

  3. ElasticSearch根据坐标点和半径查询范围内的所有记录,并按距离排序

    一.场景 es版本号5.3.0,查询es索引里距离某点位(例:113.93900469,22.56172077)两百米内的所有记录,并按距离排序 二.操作步骤 1.语法 坐标字段类型是geo_poin ...

  4. MySql中实现 按经纬度搜索附近的人,并按距离排序的简单实现

    按经纬度搜索附近的人,并按距离排序的简单实现. 2016年05月31日 23:26:17 阅读数:7235 按经纬度搜索附近的人,并按距离排序的简单实现 这是一种简单的实现,数据量不大的情况下还是能满 ...

  5. sqlserver根据经纬度查询距离范围

    首先数据库里有坐标的经度和维度字段,然后根据选择的地点经纬度和有效范围(米)来进行查询 通过百度发现了sql有自带的经纬度算法 所以直接来过来使用就行 例子: 指定一个经纬度,给定一个范围值(单位:千 ...

  6. Python 根据百度 API 获得经纬度,根据经纬度计算城市间距离

    百度提供的查询经纬度的 api 为: http://api.map.baidu.com/geocoder?address=您要查询的地址&output=xml&key=您要输入的key ...

  7. [转载]根据两点的经纬度求方位角和距离,等

    转:http://blog.sina.com.cn/s/blog_658a93570101hynw.html 原文地址:根据两点的经纬度求方位角和距离,等作者:多乎哉不多也多亦不多乎实乃少也 最近自己 ...

  8. python计算两个点之间的距离_python实现两个经纬度点之间的距离和方位角的方法...

    最近做有关GPS轨迹上有关的东西,花费心思较多,对两个常用的函数总结一下,求距离和求方位角,比较精确,欢迎交流! 1. 求两个经纬点的方位角,P0(latA, lonA), P1(latB, lonB ...

  9. 数据库查询:列出各个部门中工资高于本部门平均工资的员工信息,并按部门号排序。

    列出各个部门中工资高于本部门平均工资的员工信息,并按部门号排序. select a.deptno,count(*) from emp as a, (select deptno,avg(sal) as ...

  10. 已知一个点的经纬度、方位角、距离,求另一点经纬度

    /*** 长半径a=6378137 米*/public static double EARTH_RADIUS = 6378137;/*** 短半径b=6356752.3142*/public stat ...

最新文章

  1. Zookeeper系列五:Master选举、ZK高级特性:基本模型
  2. 跟着“土牛”学架构知识
  3. 你胆敢不加break试试?
  4. linux中iconv函数,Linux下编码转换(iconv函数族)
  5. Matplotlib 中文用户指南 7.1 交互式导航
  6. linux内核系列远程拒绝服务漏洞,预警 | Linux 爆“SACK Panic”远程DoS漏洞,大量主机受影响...
  7. 烟雾检测模块ADPD188BI介绍与应用(一)
  8. 门禁上的push是什么意思_门禁系统专业术语对照表
  9. 12306订票候补是个坑_12306网上订票候补是什么意思
  10. Alink(1):Alink概述
  11. js将数字金额用符号间隔 vue中使用逗号间隔数字金额-共享博客
  12. SEO技巧:快速学会SEO技术的方法
  13. 经典SQL查询语句大全
  14. MySQL--创建表
  15. PYNQ搭建系统-Petalinux上网方式
  16. 【Python】函数相关
  17. UNIT07 BREs EREs PREs
  18. 体验搜狐PaaS平台搜狐云景-自动调度(Autoscale)
  19. 智能合约开发——TypeScript 基础(全)
  20. 数据结构-特殊矩阵【对称矩阵、上三角下三角矩阵、三对角矩阵】的压缩存储代码实现

热门文章

  1. linux压缩命令常用:tar,tgz,gzip,zip,rar
  2. 海康视频的4G接入-实时浏览
  3. python pandas库用法_Python使用Pandas库常见操作详解
  4. 构造c语言的上下文无关文法,正则文法和上下文无关文法
  5. 电压跟随器的一点理解
  6. cad被管理员阻止_CAD注册机无法以管理员身份输入的解决方案
  7. 一款访问远程Linux服务器的web SSH终端
  8. Windows10 VMware 虚拟机桥接模式无法上网 但是和宿主机能互相ping通
  9. 大佬们用代码写的故事
  10. 【C语言】三子棋游戏详解