Null返回距离

时间:2014-05-31 14:20:55

标签: mysql

这里的SQL新词总数。我创建了两个SQL表,一个包含有关酒店的信息,另一个包含有关景点的信息。我正在尝试创建一个查询,我可以在其中输入景点的邮政编码,并让数据库返回半径为1,5和10英里的酒店距离。

SELECT 
   hotels.*, 
   attractions.*,  
   ( ( ACOS( SIN(hotels.Hotel_Lat                                  * PI() / 180) 
           * SIN(attractions.Attraction_Lat                        * PI() / 180)
         +   
             COS(hotels.Hotel_Long                                 * PI() / 180)
           * COS(attractions.Attraction_Long                       * PI() / 180)
           * COS((hotels.Hotel_Long - attractions.Attraction_Long) * PI() / 180)
           ) * 180 / PI()
     ) * 60 * 1.1515
   ) as distance  
FROM hotels 
JOIN attractions  

此查询返回距离的“Null”。我的表格中填充了lat longs和postcodes。有什么想法吗?如果这有所不同,我会有负值经度吗?

使用MySQL社区服务器5.6.17。

示例数据 - 酒店有7行数据。

Hotel_Name | Hotel_Address | Hotel_Lat | Hotel_Long
a            ST158DH        52.906438    -2.145523
b            ST161LF        52.827959    -2.129709

Attraction_Name | Attraction_Postcode | Attraction_Lat | Attraction_Long
a                   ST180BA              52.839509        -2.056964
b                   ST180TG              52.832820        -2.091124

总共有四个景点。

1 个答案:

答案 0 :(得分:0)

使用即使在非常小的距离上表现良好的Haversine formula,也可以尝试使用此代码(或MySQL的等效代码):

select
     Hotel_Name
    ,Hotel_Address
    ,Attraction_Name
    ,Attraction_Address

    ,round(2 * atn2(sqrt(a),sqrt(1-a)),                       4) as DeltaRad 
    ,round(2 * atn2(sqrt(a),sqrt(1-a)) * (180.0 / pi()),      2) as DeltaDeg 
    ,round(2 * atn2(sqrt(a),sqrt(1-a)) * (180.0 / pi()) * 60, 2) as DeltaNMs 
    ,round(2 * atn2(sqrt(a),sqrt(1-a)) * 6371.0,              2) as DeltaKMs 
from (
  select 
       Hotel_Name
      ,Hotel_Address
      ,Attraction_Name
      ,Attraction_Address

      , SinHalfDeltaLatRad * SinHalfDeltaLatRad
      + CosCosLat 
      * SinHalfDeltaLngRad * SinHalfDeltaLngRad       as a
  from (
    SELECT 
        Hotel_Name
       ,Hotel_Address
       ,Attraction_Name
       ,Attraction_Address

       ,sin((h.Lat - a.Lat) * PI() / 180.0 / 2.0) as SinHalfDeltaLatRad  
       ,sin((h.Lng - a.Lng) * PI() / 180.0 / 2.0) as SinHalfDeltaLngRad  
       ,cos(a.Lat) * cos(a.Lat)                   as CosCosLat           
    FROM hotels      as h
    cross JOIN attractions as a  
  ) t
) t

为您的样本数据提供:

Hotel_Name           Hotel_Address Attraction_Name      Attraction_Address DeltaRad               DeltaDeg               DeltaNMs               DeltaKMs
-------------------- ------------- -------------------- ------------------ ---------------------- ---------------------- ---------------------- ----------------------
HotelA               ST158DH       AttractionA          ST180BA            0.0018                 0.1                    6.02                   11.15
HotelB               ST161LF       AttractionA          ST180BA            0.0011                 0.06                   3.75                   6.94
HotelA               ST158DH       AttractionB          ST180TG            0.0015                 0.09                   5.2                    9.63
HotelB               ST161LF       AttractionB          ST180TG            0.0006                 0.03                   1.97                   3.64