Du kunne gøre værre end at se på GEOGRAPHY
datatype, for eksempel:
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
tager bredde- og længdegraden samt et SRID (Special Reference ID-nummer). I dette tilfælde er SRID 4326, som er standard bredde- og længdegrad. Da du allerede har bredde- og længdegrad, kan du bare ALTER TABLE
for at tilføje geografikolonnen, så UPDATE
at udfylde det.
Jeg har vist to måder at få dataene ud af tabellen på, men du kan ikke oprette en indekseret visning med dette (indekserede visninger kan ikke have selvtilslutninger). Du kan dog oprette en sekundær tabel, der faktisk er en cache, som er udfyldt baseret på ovenstående. Du skal så bare bekymre dig om at vedligeholde den (kan gøres gennem triggere eller en anden proces).
Bemærk, at krydssammenføjningen vil give dig 250.000.000.000 rækker, men søgningen er enkel, da du kun behøver at se på en af kolonnerne med steder (dvs. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, vil den anden give dig væsentligt færre rækker, men forespørgslen skal så overveje både kolonnen Place1 og Place2).