2016-09-05 12 views
0

SQL Server 2014データベースから特定の領域を訪問したドライバを取得しようとしています。テーブルの名前はDriverLocationHistoryです。ここでSQLサーバーのHaversine式のSQLクエリ

は、私が使用するSQLクエリです:

SELECT id, (6371 * acos(cos(radians(37)) * cos(radians(latitude)) 
* cos(radians(Longitude) - radians(-122)) + sin(radians(37)) * sin(radians(latitude)))) AS distance 
FROM DriverLocationHistory 
HAVING distance < 5 
ORDER BY distance 

私は、クエリを実行すると、私はこのエラーを取得:

Msg 207, Level 16, State 1, Line 7 
Invalid column name 'distance'. 
+0

SQL 2008よりも大きなバージョンのSQLを使用している場合は、独自の計算をローリングするのではなく、組み込みの地理データ型を使用することを検討してください。 –

+0

@BenThulどうすればいいですか? – Saadb

答えて

1

あなたはWhere句で別名を使用することはできません。これは、結果セットが生成される前、または結果セットが生成されるまでwhere句が処理され、エイリアスが結果セットが生成されるまで割り当てられないためです。集計が処理される前にエイリアスが一部の式の値に割り当てられているため、集計クエリ(グループByがある場合)でのみこれを実行できます。あなたのクエリは、where句(HAVING句である必要はありません)の両方で完全な表現を使用する必要がありますし、順に:コメントで述べたように

SELECT id, 
    (6371 * acos(cos(radians(37)) 
     * cos(radians(latitude)) 
     * cos(radians(Longitude) - radians(-122)) + sin(radians(37)) 
     * sin(radians(latitude)))) AS distance 
FROM DriverLocationHistory 
Where 6371 * acos(cos(radians(37)) 
     * cos(radians(latitude)) 
     * cos(radians(Longitude) - radians(-122)) + sin(radians(37)) 
     * sin(radians(latitude))) < 5 
ORDER BY 6371 * acos(cos(radians(37)) 
     * cos(radians(latitude)) 
     * cos(radians(Longitude) - radians(-122)) + sin(radians(37)) 
     * sin(radians(latitude))) 

、あなたは順にエイリアスを使用することができ、

それとも、あなたはまた、サブクエリで計算し、別名割り当てを実行できます。

SELECT id, distance 
From (Select (6371 * acos(cos(radians(37)) 
      * cos(radians(latitude)) 
      * cos(radians(Longitude) - radians(-122)) + 
      sin(radians(37)) 
      * sin(radians(latitude)))) distance 
     From DriverLocationHistory)z 
Where distance < 5 
ORDER BY distance 
+0

繰り返しを避けるためにネストされたクエリを使用することもできます。 'select * from(距離としてblahblahblahを選択)x x.distance <5' – Blorgbeard

+0

ですが、少なくともエイリアス化された列を使用することができます数式を3回繰り返すより少し素敵なコード – Matt

+0

私はほとんどこれをやっていないので、私はそれに精通していませんでしたが、はい、あなたは正しいです。 –

2

Iは、内蔵の地理データタイプでこれを行う方法を提供するように頼まれました。これは、コメントを少し長すぎるので、ここに行く:

ALTER TABLE [DriverLocationHistory] ADD geoLocation 
    AS geography::Point([Latitude], [Longitude], 4236); 

declare @p geography = geography::Point(37, -122, 4236); 

select * from [DriverLocationHistory] 
where geoLocation.STDistance(@p) < 5000; 

空間インデックスは、選択中のwhere句のSARGabilityに役立つはずです。