编写联接以使客户在给定邮政编码的特定距离内

时间:2013-02-09 23:39:30

标签: mysql sql

我有两个表:ZipCodes和客户。

ZipCodes包含lnglat的列,客户的列数为zipcode

我需要一个查询,以便在XXXXX个邮政编码的某个距离内获得所有客户。

我有一个查询来获取XXXXX一定距离内的所有zipcodes:

SELECT ZIPCODE,( 3959 * ACOS( COS( RADIANS( $la ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( $lo ) ) + SIN( RADIANS( $la ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance 
FROM ZipCodes 
HAVING distance <$rad 
ORDER BY distance 
LIMIT 0 , 20

我只是不知道联接如何工作或如何在SQL中说出这一点。如果您能解释任何答案,我也会感激。如果不是我也理解。

我的逻辑是:

SELECT name FROM Customers WHERE Customers.zipcode = ( SELECT ZIPCODE,( 3959 * ACOS( COS( RADIANS( $la ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( $lo ) ) + SIN( RADIANS( $la ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance 
FROM ZipCodes 
HAVING distance <$rad 
ORDER BY distance 
LIMIT 0 , 20) 

2 个答案:

答案 0 :(得分:1)

你走了。假设你的原始查询返回它应该的内容,这样的东西应该有效:

SELECT Customers.* 
FROM Customers C 
INNER JOIN 
(
    SELECT ZIPCODE,( 3959 * ACOS( COS( RADIANS( $la ) ) * COS( RADIANS( LAT ) ) * COS( RADIANS( LNG ) - RADIANS( $lo ) ) + SIN( RADIANS( $la ) ) * SIN( RADIANS( LAT ) ) ) ) AS distance 
    FROM ZipCodes 
    HAVING distance <$rad 
    ORDER BY distance LIMIT 0 , 20
) as RelevantCodes 
  ON (C.ZipCode=RelevantCodes.ZipCode)

答案 1 :(得分:0)

考虑到邮政编码不是圆形或小编,精度不是很好 - 您应该注意这一点。

此外,由于地球周长为40000km,这意味着1度纬度或经度为10000 / 90~ = 111km。

如果距离小于地球的一半(10000公里或更小),此查询应该可以正常运行:

SELECT * FROM (
    SELECT c.*,
       (   SELECT
              sqrt(pow(mod(360+lat -z.lat, 360),2)
                 + pow(mod(360+long-z.long,360),2)
              ) * 111   -- exact value is 10000 km/90 degrees
           FROM zipcodes
           WHERE zipcode = $zipcode
       ) AS distance
    FROM customers c
    JOIN zipcodes z ON (z.zipcode = c.zipcode)
) x
WHERE distance < $distance_km
ORDER BY distance