Mysql 如何根据与特定纬度/经度的距离查询Amazon红移表中的用户ID列表?
目前正在使用:Mysql 如何根据与特定纬度/经度的距离查询Amazon红移表中的用户ID列表?,mysql,sql,amazon-redshift,Mysql,Sql,Amazon Redshift,目前正在使用: SELECT uid,lat,long, ( 6371 * acos( cos( radians( value ) ) * cos( radians( lat ) ) * cos( radians( long ) - radians( value ) ) + sin(radians(value)) * sin(radians(lat))
SELECT
uid,lat,long,
(
6371 *
acos(
cos( radians( value ) ) *
cos( radians( lat ) ) *
cos(
radians( long ) - radians( value )
) +
sin(radians(value)) *
sin(radians(lat))
)
) as distance
FROM
table name
WHERE
lat IS NOT Null AND long IS NOT Null
HAVING
distance < 25
ORDER BY
distance
LIMIT
25;
MySQL有点重载了HAVING子句,允许它用作带有可用别名的WHERE子句。虽然红移没有此功能,但可以先在CTE或子查询中计算距离,然后使用“计算距离”字段,以避免重复WHERE子句中的距离计算:
如果您的红移版本不支持CTE或您不想使用CTE,则只需将上述CTE放入子查询。我为自己创建了一个自定义项:
CREATE OR REPLACE FUNCTION public.f_distance(lat1 double precision, lon1 double precision, lat2 double precision, lon2 double precision)
RETURNS double precision
IMMUTABLE AS $$
import math
if lat1==None or lat2==None or lon1==None or lon2==None:
return None
if lat1==lat2 and lon1==lon2:
return 0
else:
return (6371*math.acos(
math.cos(math.radians(lat1))*math.cos(math.radians(lat2))*math.cos(math.radians(lon2)-math.radians(lon1))+
math.sin(math.radians(lat1))*math.sin(math.radians(lat2))
)
)
$$ LANGUAGE plpythonu;
所以它可以像这样直接使用:
SELECT uid,lat,long,f_distance(search_lat,search_long,lat,long) as distance
FROM your_table
WHERE f_distance(search_lat,search_long,lat,long)<25
ORDER BY 4
LIMIT 25
@塞尔格美丽的编辑,我从未见过哈弗森/大圆不难看。@TimBiegeleisen应该归功于OP。我刚刚添加了一个标识,ctl/K。投票给美丽的ACO。@TimBiegeleisen,我喜欢使用UDF@草莓UDF的拼写是UGH,如果你改变其中两个字母:-@TimBiegeleisen我想我的是一个存储函数,效率比UDF低-但它使结束查询更容易阅读,我不知道C。这似乎会在不同用户ID上的纬度和经度列以及距离上返回重复的值,检查具有相同lat/long的不同UID的DB中是否存在问题。@NeilNandi那么这与您在问题中提出的问题不同。我已经直接回答了你原来的问题。谢谢你的解决方案。看起来很好@Tim
SELECT uid,lat,long,f_distance(search_lat,search_long,lat,long) as distance
FROM your_table
WHERE f_distance(search_lat,search_long,lat,long)<25
ORDER BY 4
LIMIT 25