Вы можете сделать хуже, чем посмотреть на тип данных GEOGRAPHY
, например:
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
принимает широту и долготу, а также SRID (номер специального справочного номера).В этом случае SRID равен 4326, что является стандартной широтой и долготой.Поскольку у вас уже есть широта и долгота, вы можете просто ALTER TABLE
добавить столбец географии, а затем UPDATE
, чтобы заполнить его.
Я показал два способа вывести данные из таблицы, однако выне может создать индексированное представление с этим (индексированные представления не могут иметь самостоятельных соединений).Однако вы можете создать вторичную таблицу, которая фактически является кешем, который заполняется на основе вышеизложенного.Тогда вам просто нужно заботиться о его поддержке (это можно сделать с помощью триггеров или другого процесса).
Обратите внимание, что перекрестное соединение даст вам 250 000 000 000 строк, но поиск прост, поскольку вам нужно только взглянуть на один из столбцов мест (т. Е. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100
, второй даст вам значительно меньше строк, нозапрос должен учитывать столбцы Place1 и Place2).