Сначала я должен объявить, что я новичок в жизни. Только что использовал PHP и MySQL в течение 4 недель. Пожалуйста, примите мои извинения заранее, если я не отформатировал этот вопрос правильно или не использую надлежащие условия использования.
Я создаю приложение для поиска магазинов. Для тестирования у меня есть таблица с названием 'location', которая содержит данные об имени, адресе и широте / долготе для 5 различных сетей ресторанов с 1500 записями (местоположения).
Я запустил приложение в качестве стандартного локатора магазина, где пользователь вводит свой адрес и расстояние в милях для поиска. Приведенный ниже код правильно возвращает эти результаты при удалении оператора GROUP BY. Например, когда пользователь вводит свой адрес и расстояние для поиска, оператор SELECT возвращает ВСЕ рестораны в пределах этого расстояния.
Мое приложение требует, чтобы было возвращено и отображено только ближайшее местоположение каждой сети ресторанов в пределах указанного пользователем расстояния. Я добавил оператор GROUP BY для достижения этой цели. Правильное количество записей возвращается с правильным именем и расстоянием от пользователя. Однако все остальные поля никогда не бывают правильными. Они кажутся случайно выбранными из других записей, которые находятся за пределами значения MIN. Например, первая возвращенная запись предназначена для МОЛОЧНОЙ КОРОЛЕВЫ на расстоянии 4,38 мили - это правильно . Однако адрес, штат, город и т. Д. Для МОЛОЧНОЙ КОРОЛЕВЫ на 4,38 миль неверны .
Я много читал о проблемах с GROUP BY и требовании использовать INNER JOIN, возможно, для решения моей проблемы? Недавние вопросы и ответы в stackoverflow касаются этого очень конкретно, см. MySQL Выбор неправильного значения столбца в запросе Group By . Во всех решениях, которые я читал до сих пор, я использовал вычисленное расстояние в качестве ключа для выполнения JOIN, и я не понимаю, как это возможно.
Вопрос 1: Как мне создать оператор SELECT, чтобы получить желаемый результат: полный ряд полей данных только для одной из каждой сети ресторанов в таблице местоположений?
Заметки о моем коде, который не так страшен , как он выглядит и не является необходимым для решения моей проблемы:
Формула триггера в MIN () вычисляет расстояние в милях между адресом пользователя (переведенным в широту / долготу) и широтой / долготой каждой записи местоположения. Поверьте мне, это работает хорошо.
Оператор ORDER BY 13: означает ЗАКАЗАТЬ по 13-му полю, указанному в SELECT, в данном случае это псевдоним «расстояние». Я упоминаю об этом, потому что я заметил, что этот синтаксис не очень известен.
Код, следующий за оператором WHERE, проверяет, находится ли адрес пользователя (в широтах / долготах) в поле с широтно-угловыми углами, которые являются указанным пользователем расстоянием для поиска. Это называется «ограничивающей рамкой». Используется для оптимизации времени поиска. Можно просто проверить, является ли «расстояние» <=, чем расстояние, введенное пользователем, но для этого потребуется прочитать весь файл местоположений. Производственная версия будет содержать около миллиона записей. Для таблицы местоположений существует индекс: (loc_lat, loc_lon, loc_id). Насколько я понимаю, использование ограничивающего прямоугольника в операторе WHERE ограничит диапазон индекса, который необходимо прочитать. Вопрос 2: Это правда, как я это реализовал, будет ли это обрабатываться, как я описал? Сохранит ли решение вопроса 1 оптимизацию? </p>
Заранее благодарю всех за помощь. Я действительно только 4 недели на MySQL и PHP и, как вы можете видеть, по моей голове?
Мой вопрос сводится к этому. Как изменить этот SELECT так, чтобы он возвращал только 1 запись таблицы местоположений с соответствующими полями для каждого loc_name, которое является минимальным расстоянием от входного адреса пользователя ??
SELECT loc_id,loc_name,loc_address_1,loc_address_2,loc_city,
loc_state,loc_postal_code,loc_phone,loc_fax,
loc_lat,loc_lon,loc_geocoded_status,
MIN( ((ACOS( SIN( $lat * PI( ) /180 ) * SIN( loc_lat * PI( ) /180 ) +
COS( $lat * PI( ) /180 ) * COS( loc_lat * PI( ) /180 ) *
COS( ($long - loc_lon) * PI( ) /180 ) ) *180 / PI( )) *60 * 1.1515) )
AS distance
FROM locations WHERE (loc_lat between $lat1 and $lat2
AND loc_lon between $lon1 and $lon2)
AND loc_geocoded_status = 1
GROUP BY loc_name
ORDER BY 13