Запрос SQL Server с «уравнением»

#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