2点間の距離を計算し、生成されたフィールドとして「Distance」を返すSQLステートメント(Accessに「LocationSearch」として保存)があります。
SELECT Int((3963*(Atn(-(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))/Sqr(-(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))*(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))+1))+2*Atn(1)))*10)/10 AS Distance, *
FROM Locations
ORDER BY (3963*(Atn(-(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))/Sqr(-(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))*(Sin(LATITUDE/57.2958)*
Sin([@lat]/57.2958)+Cos(LATITUDE/57.2958)*Cos([@lat]/57.2958)*
Cos([@lng]/57.2958-LONGITUDE/57.2958))+1))+2*Atn(1)));
表示されるすべての厄介な数学コードは、緯度と経度の座標を使用してSQLステートメントの距離(マイル単位)を計算するものです。
ただし、問題は、SQLステートメントによって生成されたDistanceフィールドが文字列として返されるように見えることです。次に、0〜45マイルの距離の場所を要求するSQLコードを追加すると、「0」から「45」までの距離の値が返されます。これには、「1017」マイルの距離の場所が含まれます。どうやら、距離フィールドはテキストフィールドであり、数値フィールドではありません。そのため、「BETWEEN」ステートメントは使用できません。同じ問題があるため、「<」と「>」を使用して評価することもできません。
上記のSQLクエリを「LocationSearch」という名前の保存済みクエリとして保存しました。このようにして、次のように、それに対して2次クエリを実行できます。
SELECT * FROM LocationSearch WHERE Distance < @MaxDistance
Accessは@lat、@ long、@ MaxDistanceパラメータを要求し、場所は距離順にレコードセットに返されます。ただし、発生する問題は、MaxDistanceを45と入力した場合です。米国の西海岸の場所を含むテーブルで、@ latが47、@ longが-122(シアトル近郊)の場合、Accessは次の値を返します。 :
また、「距離」フィールドは正しい形式であるため、数値フィールドのように見えますが、何らかの理由で、クエリは1,017マイル離れたサンディエゴの場所を返します。私の推測では、距離フィールドをテキストフィールドとして評価しており、ASCII比較では、「1017」は「0」と「45」の間にあると思います。
もう1つ、ASP 3.0(クラシック)を使用して、JETOLEDB4.0を使用してこのクエリにアクセスしています。
距離フィールドを数値として定義する方法を知っている人はいますか?
ありがとう!
- - 編集 - -
以下の回答からのHansUpのアイデアを使用して、このクエリを試して、AccessにDistanceフィールドを単精度数と見なすように強制しました。
SELECT * FROM LocationSearch WHERE CSng(Distance) < @MaxDistance
これでも、1017マイル離れたサンディエゴの場所を含む以前とまったく同じ結果が返されました。