Найти ближайший бар при поиске напитка

Задача: найти ближайший бар, где подают напитки, которые я ищу.

Здесь вы можете найти сгенерированный код MySQL http://pastebin.com/5Uc2ewUW.

Запрос API, который взаимодействует с этой проблемой, будет иметь следующие параметры

query, String, ideally the drink name 
lng, double, the starting longitude
lat, double, the starting latitude
range, integer, max distance in meters (with a default value)

Параметр запроса может выбрать более одного напитка (подумайте о поиске «Водка»).

Какой была бы хорошая стратегия для написания SQL-запроса с хорошей производительностью?

Я не очень эксперт, но моя идея состоит в том, чтобы

  • ВЫБЕРИТЕ бары в диапазоне
  • ВЫБЕРИТЕ из drink__bars, где bar_id находится в предыдущем результате выбора
  • ПРИСОЕДИНЯЙТЕСЬ к таблице напитков, чтобы получить данные о напитках

Как установить порядок в зависимости от расстояния?

Любое предложение приветствуется!

Изменить: спасибо за ответы до сих пор, но они в основном сосредоточены на расчете расстояния, и это покрыто. Я не понимаю, как заказать результат (то есть напитки) на основе расстояния от баров.

Подумайте, как этот мета-запрос

SELECT drink.id, drink.name 
FROM $DATA_POOL
WHERE drink.name LIKE '%MY_QUERY%' 
ORDER BY $ORDER

куда

  • $DATA_POOL = подмножество напитков, которые есть в барах рядом со мной (я уже могу вычислить, какие бары рядом со мной)
  • $ORDER = расстояние, которое у меня есть от бара, на основе параметров API lng и lat

person Leonardo Rossi    schedule 02.09.2014    source источник
comment
возможный дубликат Рассчитать расстояние между двумя координатами GPS   -  person Bulat    schedule 02.09.2014
comment
Спасибо @Bulat, я обновил вопрос!   -  person Leonardo Rossi    schedule 02.09.2014
comment
вам подходит ответ @TheChaos?   -  person Bulat    schedule 02.09.2014


Ответы (2)


хорошо, удалил старый ответ, так как это было не то, что вы хотели...

это больше то, что вам нужно?

SELECT
*,
@radius * 2 * ASIN(SQRT(POWER(SIN(( @startlat - abs(b.lat)) * pi() / 180 / 2),2) +
COS( @startlat * pi()/180) * COS(abs(b.lat) * pi() / 180) * POWER(SIN(( @startlng - b.lng) *
pi() / 180 / 2), 2) )) AS distance
FROM 
drinks d
JOIN drink_bars db ON (db.drink_id = d.id)
JOIN bars b ON (b.id_id = db.bar_id)
WHERE d.name LIKE '%mojito%'
ORDER BY distance ASC

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

person Olli    schedule 02.09.2014
comment
Спасибо за ответ. На самом деле это не о том, как вычислить расстояние от моей начальной широты/долготы, я отредактировал вопрос, потому что это было неясно. - person Leonardo Rossi; 02.09.2014

Итак, вы знаете, как рассчитать расстояние, допустим, у нас есть подзапрос, который это делает.

Все, что вам нужно сделать, это отсортировать по расстоянию следующим образом:

SELECT d.id, d.name 
FROM 
 drinks d INNER JOIN
 drink_bars db ON db.drink_id = d.id INNER JOIN
 (SELECT id, <formula for distance> as distance FROM bars) b ON b.id = db.bar_id
WHERE d.name = @RequestedDrink AND b.distance < @MaxDistance
ORDER BY b.distance
person Bulat    schedule 02.09.2014