Je zou erger kunnen doen dan kijken naar de GEOGRAPHY
gegevenstype, bijvoorbeeld:
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
neemt de breedte- en lengtegraad op, evenals een SRID (Special Reference ID-nummer). In dit geval is de SRID 4326, wat de standaard lengte- en breedtegraad is. Omdat je al breedte- en lengtegraad hebt, kun je gewoon ALTER TABLE
om de kolom geografie toe te voegen en vervolgens UPDATE
om het te vullen.
Ik heb twee manieren laten zien om de gegevens uit de tabel te halen, maar je kunt hiermee geen geïndexeerde weergave maken (geïndexeerde weergaven kunnen geen self-joins hebben). U kunt echter een secundaire tabel maken die in feite een cache is, die op basis van het bovenstaande wordt gevuld. U hoeft zich dan alleen maar zorgen te maken over het onderhoud ervan (kan worden gedaan via triggers of een ander proces).
Merk op dat de cross join u 250.000.000.000 rijen zal opleveren, maar zoeken is eenvoudig omdat u alleen naar een van de kolommen van de plaats hoeft te kijken (d.w.z. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, de tweede geeft u aanzienlijk minder rijen, maar de zoekopdracht moet dan rekening houden met zowel de kolom Plaats1 als Plaats2).