1

2 つのテーブルがあり、1 つには英国内のすべての郵便番号と緯度と経度が含まれています。2 つ目は、店舗の場所を含むテーブルです。

ユーザーが指定した半径内のすべての店舗 (投稿) を距離とともに、最も近いものから最も遠いものの順に返す高速検索クエリを作成する必要があります。

テーブル構造は次のとおりです。

郵便番号テーブル フィールド: ID、郵便番号、緯度、経度

Locations テーブル フィールド: 店舗名、PostID、Lat、Lng

検索すると、投稿名とそのストアに関連する情報の抽出が返されます。

ユーザーが送信した郵便番号を取得し、その緯度と経度を郵便番号テーブルから取得するクエリは、郵便番号テーブルの緯度/経度と場所の各緯度/経度の間の距離計算を実行し、ユーザーが指定した距離が必要だと思いますが、緯度/経度の2つのセット間の距離計算を作成するのはうまくいきません。

必要な距離は、最大 10 マイル、最大 20 マイル、最大 50 マイル、最大 100 マイル、および 100 マイルを超える距離です。

どんな助けでも大歓迎です。

どうもありがとう、

ダン

4

1 に答える 1

1

@OllieJones がコメントしたように、harsine式を使用して大圏距離を計算する必要があります。可能な限り多くをキャッシュするために、Google コードのPHP、MySQL、Google マップを使用したスト​​ア ロケータの作成から適応します。

ALTER TABLE Postcodes
  ADD tc DOUBLE COMMENT 'cosine of latitude',
  ADD ts DOUBLE COMMENT   'sine of latitude',
  ADD gr DOUBLE COMMENT 'longitude in radians',
  ADD UNIQUE INDEX (Postcode);

CREATE TRIGGER Postcode_insert BEFORE INSERT ON Postcodes FOR EACH ROW SET
  NEW.tc = cos(radians(NEW.Latitude)),
  NEW.ts = sin(radians(NEW.Latitude)),
  NEW.gr =     radians(NEW.Longitude);

CREATE TRIGGER Postcode_update BEFORE UPDATE ON Postcodes FOR EACH ROW SET
  NEW.tc = cos(radians(NEW.Latitude)),
  NEW.ts = sin(radians(NEW.Latitude)),
  NEW.gr =     radians(NEW.Longitude);

UPDATE Postcodes SET tc = NULL; -- trigger will do the rest

CREATE VIEW distance AS
  SELECT s.Id AS PostID, u.Postcode,
         acos(s.tc*u.tc*cos(s.gr-u.gr) + s.ts*u.ts) AS radii
  FROM   Postcodes s, Postcodes u;

その後、あなたがする必要があるのは次のとおりです。

SELECT   Locations.*, 3959 * distance.radii AS miles
FROM     Locations JOIN distance USING (PostID)
WHERE    distance.Postcode = ?
HAVING   miles < ?

sqlfiddleで参照してください。

于 2012-09-16T11:32:15.600 に答える