2016-04-18 3 views
3

У меня есть база данных со списком контактов с координатами puesdo, где они живут. Вот пример:Поиск на расстоянии в SQL

name e_point n_point 
David 102  345 
James 174  746 
Ali  460  584 
Kevin 364  479 
Mark 385  274 

мне было интересно, можно ли создать запрос, который может осуществлять поиск в пределах расстояния двух координат? Например, я хочу список людей, которые живут в радиусе 20 кв. Миль от Джеймса.

Какие функции могут помочь мне сделать это?

+0

Я думаю, что это возможно, но только если я знал, что означает «координаты puesdo». Я googled этот термин, но не смог найти ничего, что объясняло бы, что это значит –

+0

@Tin Tran: Эти координаты puesdo в основном ориентированы на восток и север. Я просто хотел использовать что-то с короткими цифрами в качестве теста, прежде чем переходить к реальности. – mrteeth

+0

так, как e_point будет как -x и n_point будет как -y? –

ответ

2

Mysql Синтаксис:

SELECT name FROM `table` WHERE SQRT(
POW(e_point - (SELECT e_point FROM `table` WHERE name='james'), 2) + 
POW(n_point - (SELECT n_point FROM `table` WHERE name='james'), 2)) < 20 
AND name <> 'james' 

Примечание:

  1. вам нужно изменить 'имя' в 3-х местах.
  2. Добавленные подзапросы позволяют запускать один запрос только с одной переменной (именем). Если удалить подзапросы, необходимо запустить 2 запросов (первый запрос извлечения Корд, а второй запроса поиска рядом людей)
  3. формулы:

enter image description here

Где p1 = (p1X, P1Y) и p2 = (p2x, p2y)

+0

Этот ответ был бы лучше, если бы он объяснил код и используемую формулу. – Schwern

+0

@Gerardo: Спасибо за предложение. Мне было интересно узнать, как объяснить функцию 'POW' и' SQRT'? Кроме того, почему причина подзапроса. Я просто спрашиваю, потому что я хочу узнать о обосновании кода. – mrteeth

+0

Ответ отредактирован: уравнение и запрос объяснены –

2

Для расчета расстояния между 2 координатами необходимо получить Great-circle distance, так как земля закруглена, и измерение расстояния зависит от этого факта.

enter image description here

Делать это с SQL будет что-то вроде этого в соответствии с Google Maps API docs:

SELECT id, (3959 * acos(cos(radians(37)) * cos(radians(lat)) * cos(radians(lng) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) 
AS distance 
FROM markers 
HAVING distance < 25 
ORDER BY distance 
LIMIT 0 , 20; 
+0

Большая дистанция круга, вероятно, переполнена на 20 миль. В чем разница, если вы предполагаете, что это на самолете? – Schwern

+0

@ Danny H: Большое спасибо за предложение и код. Я предполагаю, что это для широты и долготы? Может ли он использоваться и для других корней? – mrteeth

1

если ваши координаты представляют как х и у координаты вы можете использовать что-то вроде этого (просто заменяет вхождения contacts с фактическим именем таблицы) расстояние возвращается расстояние от «James»:

SELECT T2.name, 
     SQRT(POWER(T2.e_point-T1.e_point,2)+ 
      POWER(T2.n_point-T1.n_point,2)) as distance 
FROM contacts T1 
INNER JOIN contacts T2 ON 
    SQRT(POWER(T2.e_point-T1.e_point,2)+ 
     POWER(T2.n_point-T1.n_point,2)) <= 20 
WHERE T1.name = 'James' 
AND T1.name != T2.name 

sqlfiddle

+0

Круто, спасибо большое! Кстати, можете ли вы объяснить, почему вы использовали функции 'SQRT' и' POWER'? Просто хочу понять код немного лучше. – mrteeth

+0

SQRT дает вам квадратный корень из числа, такого как sqrt (9), равное 3 ... POWER() дает вам показатель числа, такого как POWER (3,2), равный 3 во 2-й степени, так что 3 квадрата равны 9 .. .. и вся формула основана только на теореме пифагора. –

+0

А, я вижу. Это для объяснения. Я смотрел на формулу формулы пифагора и имеет смысл. – mrteeth

Смежные вопросы