Vous pourriez faire pire que de regarder la GEOGRAPHY
type de données, par exemple :
CREATE TABLE Places
(
SeqID INT IDENTITY(1,1),
Place NVARCHAR(20),
Location GEOGRAPHY
)
GO
INSERT INTO Places (Place, Location) VALUES ('Coventry', geography::Point(52.4167, -1.55, 4326))
INSERT INTO Places (Place, Location) VALUES ('Sheffield', geography::Point(53.3667, -1.5, 4326))
INSERT INTO Places (Place, Location) VALUES ('Penzance', geography::Point(50.1214, -5.5347, 4326))
INSERT INTO Places (Place, Location) VALUES ('Brentwood', geography::Point(52.6208, 0.3033, 4326))
INSERT INTO Places (Place, Location) VALUES ('Inverness', geography::Point(57.4760, -4.2254, 4326))
GO
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
FROM Places p1
CROSS JOIN Places p2
GO
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
FROM Places p1
INNER JOIN Places p2 ON p1.SeqID > p2.SeqID
GO
geography::Point
prend la latitude et la longitude ainsi qu'un SRID (Special Reference ID number). Dans ce cas, le SRID est 4326 qui est la latitude et la longitude standard. Comme vous avez déjà la latitude et la longitude, vous pouvez simplement ALTER TABLE
pour ajouter la colonne géographie puis UPDATE
pour le remplir.
J'ai montré deux façons d'extraire les données de la table, mais vous ne pouvez pas créer de vue indexée avec cela (les vues indexées ne peuvent pas avoir d'auto-jointures). Vous pouvez cependant créer une table secondaire qui est en fait un cache, qui est remplie en fonction de ce qui précède. Vous n'avez ensuite qu'à vous soucier de sa maintenance (cela peut être fait via des déclencheurs ou un autre processus).
Notez que la jointure croisée vous donnera 250 000 000 000 lignes, mais la recherche est simple car vous n'avez qu'à regarder l'une des colonnes de lieux (c'est-à-dire SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, la seconde vous donnera beaucoup moins de lignes, mais la requête doit alors prendre en compte à la fois les colonnes Place1 et Place2).