Możesz zrobić coś gorszego niż spojrzeć na GEOGRAPHY
typ danych, na przykład:
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
pobiera szerokość i długość geograficzną oraz SRID (Special Reference ID number). W tym przypadku SRID to 4326, co jest standardową szerokością i długością geograficzną. Ponieważ masz już szerokość i długość geograficzną, możesz po prostu ALTER TABLE
aby dodać kolumnę geograficzną, a następnie UPDATE
aby go zapełnić.
Pokazałem dwa sposoby na wydobycie danych z tabeli, jednak nie można za pomocą tego utworzyć widoku indeksowanego (widoki indeksowane nie mogą mieć sprzężeń własnych). Możesz jednak utworzyć dodatkową tabelę, która jest w rzeczywistości pamięcią podręczną, która jest wypełniana na podstawie powyższego. Następnie musisz się tylko martwić o utrzymanie go (można to zrobić za pomocą wyzwalaczy lub innego procesu).
Zauważ, że połączenie krzyżowe daje 250 000 000 000 wierszy, ale wyszukiwanie jest proste, ponieważ wystarczy spojrzeć na jedną z kolumn miejsc (np. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, druga da znacznie mniej wierszy, ale zapytanie musi wtedy uwzględniać zarówno kolumnę Place1 jak i Place2.