给定了经纬度的一张my_latlng表,和一个my_grid表,怎么实现my_latlng表回mygrid中的id?
- 场景:
假设我们拥有一个拥有了一系列经纬度的表my_latlng(lat string,lng string)表,还有一张给定的栅格表my_grid(gridid bigint,centerlng double,centerlat double,gridx int,gridy int,minlng double,maxlng double,minlat double,maxlat double)并且栅格的为一个边长为5m的正方形,其中:
gridid :栅格id
centerlng:栅格中心点经度
centerlat :栅格中心点纬度
gridx :栅格x轴方向的坐标位置
gridy :栅格y轴方向的坐标位置
需求:给my_latlng表找它所落的栅格的id,如果my_latlng中的经纬度,在总体栅格以外,就不参与运算。
- 解决方案一:
由于栅格有最大、最小经纬度,因此可以直接使用栅格的经纬度范围来给my_latlng表回填栅格id:
- select t11.gridid,t10.lat,t10.lng
- from my_latlng t10 inner join my_grid t11
- where t10.lat>=t11.minlat and t10.lat<=t11.maxlat
- and t10.lng>=t11.minlng and t10.lng<t11.minlng;
缺陷:该种方案缺陷inner join 是没有on条件的,如果在hive中是没有办法把>=,>,<,<=符号给写到inner join 中 on条件上的,语法问题吧。
因此,上边这条语句是执行的一个cross join,如果my_latlng表有1000wt条记录,而my_grid有10000w条记录时,这样的一个cross join 在加上 where条件,就会导致这个数据在集群中1000spark套餐(假设说1spark套餐:1vcore cpu+12g memory+500g disk。),5个小时也无法分析出结果。
- 解决方案二:
我们知道经纬度小数点第5位代表的基本就是米单位,纬度30°时,经度每变化0.00001相当于变化1.1m。因此,我们可以粗略的认为5m的栅格在经度、纬度上的变化为0.00005个单位的变化。
因此,利用上边的这个特性我们可以有以下方案:
第一步、可以找到某些栅格距离自己纬度和经度变化接近5m的周围8+1个左右的栅格;
- (
- rpad(t10.lat+0.00005,7,'')=rpad(t11.centerlat,7,'')
- or rpad(t10.lat,7,'')=rpad(t11.centerlat+0.00005,7,'')
- or rpad(t10.lat,7,'')=rpad(t11.centerlat,7,'')
- )
- and
- (
- rpad(t10.lng+0.00005,8,'')=rpad(t11.centerlng,8,'')
- or rpad(t10.lng,8,'')=rpad(t11.centerlng+0.00005,8,'')
- or rpad(t10.lng,8,'')=rpad(t11.centerlng,8,'')
- )
备注:我们计算范围:经度范围100.0到180.0,纬度范围为:10.0到90.0。
第二步、从第一步中的栅格中挑选距离自己最近的一个栅格作为自己归属栅格。
- (
(cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)
) distans
但是上边的程序如果放在hive中的语句因该是这么写:
- select t11.gridid,t10.lat,t10.lng,(
(cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) distans- from my_latlng t10 inner join my_grid t11
- where (
- rpad(t10.lat+0.00005,7,'')=rpad(t11.centerlat,7,'')
- or rpad(t10.lat,7,'')=rpad(t11.centerlat+0.00005,7,'')
- or rpad(t10.lat,7,'')=rpad(t11.centerlat,7,'')
- )
- and(
rpad(t10.lng+0.00005,8,'')=rpad(t11.centerlng,8,'')- or rpad(t10.lng,8,'')=rpad(t11.centerlng+0.00005,8,'')
- or rpad(t10.lng,8,'')=rpad(t11.centerlng,8,'')
- );
但是上边的程序是有以下两个问题:
问题1)inner join 没有 on 条件,原因是where中语句不允许写到on中,也是hive的语法问题;
问题2)上边这段代码也是执行的cross join,而此自然执行的也很慢。
好的事情是:
1)从这段代码中,我们是可以把多个语句拆分出9个语句,而且这9个语句是可以具有on条件的;
2)之后把9个语句分析的结果union all后的结果,再进行按照my_latlng.lat,my_latlng.lng分组求出具体每个经纬度的最小距离值;
3)使用“my_latlng的经纬度+最小距离”与“union all后的结果”进行一次inner join,就可以得到具体每个经纬度对应的栅格id。
具体代码:
- hiveContext.sql("create table my_latlng_gridid_distance(gridid bigint,lat string,lng string,distance decimal(38,5))")
- hiveContext.sql("create table my_latlng_mindistance(lat string,lng string,min_distans decimal(38,5))")
- hiveContext.sql("create table my_latlng_gridid_result(gridid bigint,lat string,lng string)")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat+0.00005,7,'0')=rpad(t11.centerlat,7,'0') and (rpad(t10.lng+0.00005,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp00")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp00")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat+0.00005,7,'0')=rpad(t11.centerlat,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng+0.00005,8,'0')").registerTempTable("temp01")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp01")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat+0.00005,7,'0')=rpad(t11.centerlat,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp02")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp02")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat+0.00005,7,'0') and (rpad(t10.lng+0.00005,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp10")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp10")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat+0.00005,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng+0.00005,8,'0')").registerTempTable("temp11")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp11")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat+0.00005,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp12")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp12")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat,7,'0') and (rpad(t10.lng+0.00005,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp20")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp20")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng+0.00005,8,'0')").registerTempTable("temp21")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp21")
- hiveContext.sql("select t11.gridid,t10.lat,t10.lng,cast(((cast(t10.lng as double)-t11.centerlng)*(cast(t10.lng as double)-t11.centerlng)
+(cast(t10.lat as double)-t11.centerlat)*(cast(t10.lat as double)-t11.centerlat)) *10000000000000 as decimal(38,5)) distans
from my_latlng t10 inner join my_grid t11
on rpad(t10.lat,7,'0')=rpad(t11.centerlat,7,'0') and rpad(t10.lng,8,'0')=rpad(t11.centerlng,8,'0')").registerTempTable("temp22")- hiveContext.sql("insert into my_latlng_gridid_distance select * from temp22")
- hiveContext.sql("select lat,lng,min(distans) as min_distans " +
- "from my_latlng_gridid_distance " +
- "group by lat,lng").repartition().persist().registerTempTable("temp_10000")
- hiveContext.sql("insert into my_latlng_mindistance select * from temp_10000")
- hiveContext.sql("select t11.gridid,t11.lat,t11.lng " +
- "from my_latlng_mindistance as t10 " +
- "inner join my_latlng_gridid_distance as t11 " +
- "on t10.lat=t11.lat and t10.lng=t11.lng and t10.min_distans=t11.distans")
- .distinct() // must use distinct
- .repartition().persist().registerTempTable("temp_20000")
- hiveContext.sql("insert into my_latlng_gridid_result select * from temp_20000")
上边分区了9中情况,实际上是可以在简化为4种情况如下:
- val df00 = hiveContext.sql("select t11.gridid,t10.key,t10.objectid,t10.longitude,t10.latitude,cast(((t10.longitude-t11.longitude)*(t10.longitude-t11.longitude)+(t10.latitude-t11.latitude)*(t10.latitude-t11.latitude))*10000000000000 as decimal(38,5)) distans,t10.averageltescrsrp as rsrp,t10.samecount " +
- "from m_join_s_" + city + " as t10 " +
- "inner join fl_" + city + " as t11 on rpad(t10.latitude+0.00005,7,'')=rpad(t11.latitude+0.00005,7,'') and rpad(t10.longitude,8,'')=rpad(t11.longitude,8,'')")
- .repartition(200).persist()
- df00.registerTempTable("temp_df00" + city)
- hiveContext.sql("insert into my_result" + city + " select * from temp_df00" + city)
- val df01 = hiveContext.sql("select t11.gridid,t10.key,t10.objectid,t10.longitude,t10.latitude,cast(((t10.longitude-t11.longitude)*(t10.longitude-t11.longitude)+(t10.latitude-t11.latitude)*(t10.latitude-t11.latitude))*10000000000000 as decimal(38,5)) distans,t10.averageltescrsrp as rsrp,t10.samecount " +
- "from m_join_s_" + city + " as t10 " +
- "inner join fl_" + city + " as t11 on rpad(t10.latitude+0.00005,7,'')=rpad(t11.latitude+0.00005,7,'') and rpad(t10.longitude+0.00005,8,'')=rpad(t11.longitude+0.00005,8,'')")
- .repartition(200).persist()
- df01.registerTempTable("temp_df01" + city)
- hiveContext.sql("insert into my_result" + city + " select * from temp_df01" + city)
- val df02 = hiveContext.sql("select t11.gridid,t10.key,t10.objectid,t10.longitude,t10.latitude,cast(((t10.longitude-t11.longitude)*(t10.longitude-t11.longitude)+(t10.latitude-t11.latitude)*(t10.latitude-t11.latitude))*10000000000000 as decimal(38,5)) distans,t10.averageltescrsrp as rsrp,t10.samecount " +
- "from m_join_s_" + city + " as t10 " +
- "inner join fl_" + city + " as t11 on rpad(t10.latitude,7,'')=rpad(t11.latitude,7,'') and rpad(t10.longitude+0.00005,8,'')=rpad(t11.longitude+0.00005,8,'')")
- .repartition(200).persist()
- df02.registerTempTable("temp_df02" + city)
- hiveContext.sql("insert into my_result" + city + " select * from temp_df02" + city)
- val df03 = hiveContext.sql("select t11.gridid,t10.key,t10.objectid,t10.longitude,t10.latitude,cast(((t10.longitude-t11.longitude)*(t10.longitude-t11.longitude)+(t10.latitude-t11.latitude)*(t10.latitude-t11.latitude))*10000000000000 as decimal(38,5)) distans,t10.averageltescrsrp as rsrp,t10.samecount " +
- "from m_join_s_" + city + " as t10 " +
- "inner join fl_" + city + " as t11 on rpad(t10.latitude,7,'')=rpad(t11.latitude,7,'') and rpad(t10.longitude,8,'')=rpad(t11.longitude,8,'')")
- .repartition(200).persist()
- df03.registerTempTable("temp_df03" + city)
- hiveContext.sql("insert into my_result" + city + " select * from temp_df03" + city)
解决方案三:
- select t10.CITY,t11.OBJECTID,t11.POINT_NAME,COUNT(0) OTTCOUNT, sum(CASE WHEN t10.RP<=-110 then 1 else 0 end) WEAKOTTCOUNT
- from (
- select t1.OBJECTID,t2.city,t2.RP,t2.longitude,t2.latitude
- from SENSE_ZJ t1
- inner join TEMP_OTT_HANGZHOU t2
- on rpad((t1.miny+t1.maxy)/2,5,'')=rpad(t2.latitude,5,'') and rpad((t1.minx+t1.maxx)/2,6,'')=rpad(t2.longitude,6,'')
- where t1.SENSE_NAME='xxx'
- )t10
- inner join SENSE_ZJ t11 on t10.OBJECTID=t11.OBJECTID
- where t10.longitude >= t11.minx and t10.longitude <= t11.maxx and t10.latitude >= t11.miny and t10.latitude <= t11.maxy
- group by t10.CITY,t11.OBJECTID,t11.POINT_NAME
- order by objectid
给定了经纬度的一张my_latlng表,和一个my_grid表,怎么实现my_latlng表回mygrid中的id?的更多相关文章
- mysql依据某一张表的字段,查询出对应的表所在的数据库
表太多,只记得这个表有一个mygame的字段,但是并不知道这张表在那个数据库下,只能根据这个字段查找对应的表和所在数据库 select table_schema,table_name from inf ...
- sql server2008怎么给一张表加一个用户
有时候我们要对数据库进行权限管理,防止有人误操作或者窃取数据,那么小编这篇文章就是实现这个的操作过程. 百度经验:jingyan.baidu.com 工具/原料 sql server2008数据库 ...
- Mysql分表和分区的区别、分库分表介绍与区别
分表和分区的区别: 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这 ...
- jQuery编程基础精华02(属性、表单过滤器,元素的each,表单选择器,子元素过滤器(*),追加方法,节点,样式操作)
属性.表单过滤器 属性过滤选择器: $("div[id]")选取有id属性的<div> $("div[title=test]")选取title属性为 ...
- hbase操作(shell 命令,如建表,清空表,增删改查)以及 hbase表存储结构和原理
两篇讲的不错文章 http://www.cnblogs.com/nexiyi/p/hbase_shell.html http://blog.csdn.net/u010967382/article/de ...
- 一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数
一个表中的id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数 select id ,Count(*) from table_name group by id having count( ...
- {MySQL的库、表的详细操作}一 库操作 二 表操作 三 行操作
MySQL的库.表的详细操作 MySQL数据库 本节目录 一 库操作 二 表操作 三 行操作 一 库操作 1.创建数据库 1.1 语法 CREATE DATABASE 数据库名 charset utf ...
- sqlserver 删除表中数据 id 从1开始
TRUNCATE TABLE TbName --TbName是表名 但如果TbName中某些字段与其它表有主外键关系,会报错: 无法截断表 'Plants',因为该表正由 FOREIGN KE ...
- 什么是分表和分区 MySql数据库分区和分表方法
1.为什么要分表和分区 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性 ...
随机推荐
- MongoDb进阶实践之一 如何在Linux(CentOS 7)上安装MongoDB
一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是 ...
- 【Python&数据结构】 抽象数据类型 Python类机制和异常
这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Pyt ...
- 关于换了手机后,导致原来连的fiddler抓不到新手机上的包的解决方法
原来我们测试都是一台安卓机,一台ios机,由于机子不够,所以安卓机都是自己的手机,可以连内网,也可以连外网 但是最近这几天,不知道公司抽了什么风.把网都给限制了,只有公司的测试机,才能连内网测,结果我 ...
- jQuery学习笔记 .addClass()/.removeClass()简单学习
使用jQuery或javaScript来动态改变页面中某个或部分元素的样式,为了实现这样的功能,我们往往都是使用jQuery或javaScript来控制HTML中DOM的类名(class)从而实现增加 ...
- New UWP Community Toolkit - Staggered panel
概述 前面 New UWP Community Toolkit 文章中,我们对 2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 Staggered panel,本篇我们结合代码详细讲解 St ...
- Java基础学习笔记十九 IO
File IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了.那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再 ...
- (译文)学习ES6非常棒的特性——Async / Await函数
try/catch 在使用Async/Await前,我们可能这样写: const main = (paramsA, paramsB, paramsC, done) => { funcA(para ...
- MySQL之数据的简单查询
我直接把我的mysql学习笔记以图片的形式粘贴在这里了,供自己回顾(都是一些简单的语句)
- C第十八次课
总结知识点: 指针 1.指针变量 指针变量的定义:例8.1 指针变量的引用:例8.2: 指针变量作为函数参数:例8.3 swap函数,例8.4 比较排序函数 2.指针数组 数组元素的指针:int *p ...
- Beta Scrum Day 2
听说