-3

我有两个表:邮政编码和客户。

ZipCodes 有lng和列lat,客户有zipcode.

我需要一个查询来让所有客户都拥有一定距离的XXXXX邮政编码。

我有一个查询要获取 XXXXX 一定距离内的所有邮政编码:

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) 
4

2 回答 2

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)
于 2013-02-10T00:00:59.397 回答
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
于 2013-02-10T00:06:49.283 回答