Du kan göra värre än att titta på GEOGRAPHY
datatyp, till exempel:
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
tar latitud och longitud samt ett SRID (Special Reference ID-nummer). I det här fallet är SRID 4326 vilket är standardlatitud och longitud. Eftersom du redan har latitud och longitud kan du bara ALTER TABLE
för att lägga till geografikolumnen och sedan UPDATE
för att fylla den.
Jag har visat två sätt att få ut data från tabellen, men du kan inte skapa en indexerad vy med detta (indexerade vyer kan inte ha självanslutningar). Du kan dock skapa en sekundär tabell som i praktiken är en cache, som fylls i baserat på ovanstående. Du behöver då bara oroa dig för att underhålla den (kan göras genom triggers eller någon annan process).
Observera att korskopplingen ger dig 250 000 000 000 rader, men sökningen är enkel eftersom du bara behöver titta på en av platskolumnerna (dvs. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, den andra ger dig betydligt färre rader, men frågan måste då ta hänsyn till både kolumnen Plats1 och Plats2).