#sql #sql-server #sql-server-2008
#sql #sql-сервер #sql-server-2008
Вопрос:
Я пытаюсь выяснить, как построить SQL-запрос следующим образом:
У меня есть координаты, сохраненные в моей базе данных SQL Server, и я пытаюсь выбрать все записи на указанном расстоянии от точки.
Есть идеи, как это сделать?
Комментарии:
1. Прежде всего, какие координаты линейные или 3d, поскольку вычисление расстояний в обоих случаях будет разным. Также было бы очень полезно получить некоторый код и информацию о базе данных.
2. Если ваши координаты хранятся с использованием типа данных geography, вы можете использовать метод STDistance, чтобы получить расстояние от вашей точки — см. msdn.microsoft.com/en-us/library/bb933952.aspx .
Ответ №1:
SELECT *
FROM YourTable
INNER JOIN
(SELECT (sqrt( ( xDestination - xOrigin)^2 ( yDestination - yOrigin)^2 )) AS Distance
FROM YourTable) AS computed ON YourTable.id = computed.id
WHERE computed.Distance = SpecifiedDistance
Я не знаю ваших точных определений и того, как вы хотели бы обрабатывать ввод координат, поскольку я не знаю, используете ли вы язык на стороне сервера для ввода данных, так что это всего лишь общий пример
Ответ №2:
Это интереснее, чем кажется на первый взгляд, потому что вы говорите «на указанном расстоянии».
Первым простым решением является вычисление расстояния по Пифагору, то есть
SELECT * FROM myTable
WHERE SQRT( (myPositionX - @pointX)^2 (myPositionY - @pointY)^2 ) = @myDistance
Однако сравнение переменных с плавающей запятой никогда не является хорошей идеей из-за неточностей, и в данном случае это усугубляется из-за квадратного корня, который вам на самом деле не нужен. Очевидно, что если расстояние от A до B равно X, то квадрат расстояния от A до B также равен квадрату X. Следовательно, следующим сокращением будет
SET @mySqrDistance = @myDistance^2
SELECT * FROM myTable
WHERE ( (myPositionX - @pointX)^2 (myPositionY - @pointY)^2 ) = @mySqrDistance
Это не только делает is более точным из-за удаления SQRT, но и намного быстрее по той же причине (функции с квадратным корнем, хотя и оптимизированы, работают медленно). Однако у вас все еще есть проблема сравнения значений с плавающей точкой в некоторой степени (конечно, это зависит от специфики SQL и используемых типов столбцов, но в целом), поэтому лучшим подходом может быть
SET @mySqrDistanceMin = (@myDistance-@myError)^2
SET @mySqrDistanceMax = (@myDistance @myError)^2
SELECT * FROM myTable
WHERE ( (myPositionX - @pointX)^2 (myPositionY - @pointY)^2 )
BETWEEN @mySqrDistanceMin AND mySqrDistanceMax