1

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マイル離れたサンディエゴの場所を含む以前とまったく同じ結果が返されました。

4

3 に答える 3

2

Durationそのフィールド式からテキストの代わりに数値を返す方法が見つからない場合は、クエリをサブクエリとして使用してからDuration、含まれているクエリにキャストします。

SELECT CSng(sub.Duration) AS Duration_as_single
FROM
    (
        -- your existing query --
    ) AS sub
WHERE CSng(sub.Duration) BETWEEN 0 AND 45
ORDER BY 1;

そのアプローチはまた、より良いものになりORDER BYます...それが何かに重要であるならば。:-)

于 2013-01-04T20:41:47.920 に答える
1

select *FROMおよびandORDER BY句なしでクエリを試しました。SELECTアクセスのグリッドで文字列が左寄せとして返されることを証明するために、に追加の列を追加しました。

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, 
'test' as test

4つのパラメーターの入力を求められましたが、最終的に2列のテーブルが返されました。

ここに画像の説明を入力してください

最初の列は右寄せで、2番目の列(明らかに文字列)は左寄せであるため、アクセスによって実際に数値として返されているように見えます。これはAccess2010にありました。

-編集-

と呼ばれる新しい2列のテーブルを作成しましたLocations。フィールドid(自動番号)とフィールドField1(テキスト)があります。OPによって提供された元のクエリを実行しましたが、正常に機能します(距離は数値として返されます)。

これは不思議につながります...OPのLocationsテーブルには独自のDistanceフィールド、つまり文字列がありますか?それ以外の場合、問題はSQLステートメントを呼び出すコードにある必要があり、ステートメントやジェットエンジン自体にはありません。

于 2013-01-04T20:31:27.120 に答える
1

さて、それを解決しました!

HansUp、あなたのアイデアが解決策であることが判明しました。CSng()SQLクエリのパラメータに関数を追加してみました@MaxDistanceが、それで修正されました。

変更されたセカンダリSQLクエリは次のとおりです。

SELECT * FROM LocationSearch WHERE CSng(Distance) < CSng(@MaxDistance)

皆さん、助けてくれてありがとう!あなたはみんなロックします。

あけましておめでとう。

于 2013-01-04T22:30:41.733 に答える