mySql - поиск клиентов возле определенного города - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь создать запрос, чтобы найти всех клиентов в пределах X миль от заданного города и штата, используя в основном следующую структуру таблицы:

Users Table
-----------
ID

PersonsName

ZipCode

Zipcodes Table (contains all ZIPs in the US)
--------------------------------------------
ID

ZipCode

City

State

latitude

longitude

Itбыло бы легко найти ближайших пользователей, если бы я уже знал широту / долготу города, который меня интересует, как в следующем запросе:

SELECT ID from Users u
JOIN Zipcodes z1 ON u.zipcode = z1.zipcode
WHERE 
COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*[desired latitude]/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*[desired latitude]/180.0)*COS(PI()*[desired longitude]/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance]

Однако я хочу использовать названия городов иСокращения штатов, чтобы их было легче вводить, затем запрос должен использовать этот лат / лнг для сравнения расстояний.

Я думаю, я мог бы написать два запроса, первый, чтобы получить широту / долготу нужного городазатем второй, чтобы использовать результаты, чтобы найти использование на определенном расстоянии от возвращенной пары широта / долгота, но можно ли его объединить в один запрос, который получает правильный широта / долгота для совпадения города, а затем использует его в расчете расстояниякоторый находится в предложении WHERE?

Не могу понять, как его обработать, чтобы найти широту / долготу для города и затем использовать в том же запросе расстояние.

Надеясь, что один из наших сотрудников сможет просто ввести город / штат и желаемое расстояние, и код вернет всех клиентов, которые подали заявку.Код получит только первое совпадение для определенного города (для больших городов может быть много записей в таблице ZIP), но это хорошо для наших целей (и поэтому мы можем просто использовать первое совпадение).

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Я согласен, что геокодирование будет обрабатывать большую часть крайних случаев, не охватываемых этим запросом, но если вы ищете быстрое и грязное исправление, используя только те инструменты, которые у вас под рукой, я считаю, что следующий запрос будет работать для вас.

SELECT ID from Users u
  JOIN Zipcodes z1 ON u.zipcode = z1.zipcode
  join (select latitude as desired_latitude, longitude as desired_longitude from Zipcodes limit 1 where City = '[user input]' and State = '[user input]' limit 1)
WHERE
  COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*[desired latitude]/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*[desired latitude]/180.0)*COS(PI()*[desired longitude]/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance];

Хотя в вашей пользовательской таблице будет больше строк, чем в таблице Zipcodes, вы, вероятно, захотите реорганизовать этот запрос так:

SELECT ID from Users u
  JOIN (
          select z1.zipcode from Zipcodes z1
          join (select latitude as desired_latitude, longitude as desired_longitude from Zipcodes limit 1 where City = '[user input]' and State = '[user input]' limit 1)
          WHERE COS(SIN(PI()*z1.latitude/180.0)*SIN(PI()*desired_latitude/180.0)+COS(PI()*z1.latitude/180.0)*COS(PI()*desired_latitude/180.0)*COS(PI()*desired_longitude/180.0-PI()*z1.longitude/180.0))*3963.0 <= [desired distance]
       ) as zipsInRange ON u.zipcode = zipsInRange.zipcode;
0 голосов
/ 01 мая 2019

Похоже, вам может понадобиться геокодирование для перевода названий городов в координаты.Доступно множество хороших API (Google, Algolia, Mapbox и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...