#php #mysql #database
Вопрос:
У меня есть две таблицы MySQL, а именно gym_activity и gym_information. Я использовал gym_id, который находится в обеих таблицах, чтобы соединить две таблицы, создав внешние ключи. Я хочу использовать внутреннее соединение, чтобы получить широту и долготу из таблицы 2(gym_information) и использовать его для вычисления радиуса и возврата предложений, которые находятся ближе всего из таблицы gym_activity. Я использовал приведенный ниже алгоритм в запросе MySQL, но я получаю ошибку:
#1054 — Неизвестная колонка «Информация о спортзале».широта» в «списке полей»
SELECT * FROM (
SELECT *,
(
(
(
acos(
sin(( -42.886963699999995 * pi() / 180))
*
sin(( `gym_information.latitude` * pi() / 180)) cos(( -42.886963699999995 * pi() /180 ))
*
cos(( `gym_information.latitude` * pi() / 180)) * cos((( 147.3199527 - `gym_information.longitude`) * pi()/180)))
) * 180/pi()
) * 60 * 1.1515 * 1.609344
)
as distance FROM `gym_activity` JOIN gym_information ON gym_information.gym_id=gym_activity.gym_id
) markers
WHERE distance <= 150
LIMIT 15;
Помощь была бы признательна. Спасибо
Комментарии:
1. Удалите обратные ссылки из вашего запроса.
Ответ №1:
Возможно, этот сценарий мог бы достичь желаемых результатов (см.: https://www.movable-type.co.uk/scripts/latlong-db.html)
<?php
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - */
/* Selection of points within specified radius of given lat/lon (c) Chris Veness 2008-2016 */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
require 'inc/dbparams.inc.php'; // defines $dsn, $username, $password
$db = new PDO($dsn, $username, $password);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$lat = $_GET['lat']; // latitude of centre of bounding circle in degrees
$lon = $_GET['lon']; // longitude of centre of bounding circle in degrees
$rad = $_GET['rad']; // radius of bounding circle in kilometers
$R = 6371; // earth's mean radius, km
// first-cut bounding box (in degrees)
$maxLat = $lat rad2deg($rad/$R);
$minLat = $lat - rad2deg($rad/$R);
$maxLon = $lon rad2deg(asin($rad/$R) / cos(deg2rad($lat)));
$minLon = $lon - rad2deg(asin($rad/$R) / cos(deg2rad($lat)));
$sql = "Select Id, Postcode, Lat, Lon,
acos(sin(:lat)*sin(radians(Lat)) cos(:lat)*cos(radians(Lat))*cos(radians(Lon)-:lon)) * :R As D
From (
Select Id, Postcode, Lat, Lon
From MyTable
Where Lat Between :minLat And :maxLat
And Lon Between :minLon And :maxLon
) As FirstCut
Where acos(sin(:lat)*sin(radians(Lat)) cos(:lat)*cos(radians(Lat))*cos(radians(Lon)-:lon)) * :R < :rad
Order by D";
$params = [
'lat' => deg2rad($lat),
'lon' => deg2rad($lon),
'minLat' => $minLat,
'minLon' => $minLon,
'maxLat' => $maxLat,
'maxLon' => $maxLon,
'rad' => $rad,
'R' => $R,
];
$points = $db->prepare($sql);
$points->execute($params);
?>
<html>
<table>
<? foreach ($points as $point): ?>
<tr>
<td><?= $point->Postcode ?></td>
<td><?= number_format($point->Lat,4) ?></td>
<td><?= number_format($point->Lon,4) ?></td>
<td><?= number_format($point->D,3) ?></td>
</tr>
<? endforeach ?>
</table>
</html>
Ответ №2:
Проблема в том, как вы использовали здесь обратные галочки:
`gym_information.latitude`
Вы должны отдельно окружить имя таблицы и имя столбца:
`gym_information`.`latitude`
Комментарии:
1. Это решает проблему, но теперь я получаю эту ошибку: #1060 — Дубликат имени столбца «идентификатор» У меня есть идентификатор столбца в обеих таблицах. Я просто получаю доступ к широте и долготе на основе внешнего ключа.
2. @sndp Не использовать
SELECT *...
. В любом случае это плохая практика, но это означает, что вы выбираетеID
столбец в обеих таблицах. Перечислите столбцы, которые вы хотите, и только эти столбцы.