1

我正在尝试根据社区邮政编码并将Haversine 公式与此处描述的 SQL 一起使用,将最近的位置分配给社区。我需要返回一个标量值,但我似乎无法避免使用第二个计算距离值来确定最近的位置。帮助。

UPDATE Community AS c
    JOIN Postcode p on p.id = c.postcode_id
    JOIN (
        SELECT 100.0 AS radius, 111.045 AS distance_unit
    ) AS a
SET c.location_id = (
    SELECT l.id,
        a.distance_unit
            * DEGREES(ACOS(COS(RADIANS(p.latitude))
            * COS(RADIANS(l.latitude))
            * COS(RADIANS(p.longitude - l.longitude))
            + SIN(RADIANS(p.latitude))
            * SIN(RADIANS(l.latitude)))) AS distance
    FROM Location AS l
    WHERE l.latitude
        BETWEEN p.latitude  - (a.radius / a.distance_unit)
            AND p.latitude  + (a.radius / a.distance_unit)
    AND l.longitude
        BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
            AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
    HAVING distance <= a.radius
    ORDER BY distance
    LIMIT 1
)
4

1 回答 1

2

使用您拥有的结构,您需要将距离计算移到WHEREandORDER BY子句中:

SET c.location_id = (
    SELECT l.id
    FROM Location AS l
    WHERE l.latitude
        BETWEEN p.latitude  - (a.radius / a.distance_unit)
            AND p.latitude  + (a.radius / a.distance_unit)
    AND l.longitude
        BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
            AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
    AND a.distance_unit
            * DEGREES(ACOS(COS(RADIANS(p.latitude))
            * COS(RADIANS(l.latitude))
            * COS(RADIANS(p.longitude - l.longitude))
            + SIN(RADIANS(p.latitude))
            * SIN(RADIANS(l.latitude)))) <= a.radius
    ORDER BY a.distance_unit
            * DEGREES(ACOS(COS(RADIANS(p.latitude))
            * COS(RADIANS(l.latitude))
            * COS(RADIANS(p.longitude - l.longitude))
            + SIN(RADIANS(p.latitude))
            * SIN(RADIANS(l.latitude)))) 
    LIMIT 1
)
于 2015-07-05T13:31:18.447 回答