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