Намерение (x == 10)
:
if (x = 10) {
//Do something
}
я думал, что никогда не буду делать эту ошибку сам, но я на самом деле недавно сделал это.
ЕСТЬ НИЧЕГО НЕПРАВИЛЬНО с этим query?
На мой взгляд, предложение WHERE будет медленным из-за задействованной математики, а использование функций в предложении WHERE предотвратит использование базой данных индекса для ускорения запроса - так что, по сути, вы будете исследуйте каждый ресторан в базе данных и выполняйте математические вычисления по дуге большого круга для каждой строки каждый раз, когда вы делаете запрос.
Лично я бы вычислил координаты TopLeft и BottomRight квадрата (которые нужно только грубо вычислить используя pythagoras) со сторонами, равными диапазону, который вы ищете, а затем выполните более сложный тест предложения WHERE для меньшего подмножества записей, которые находятся в пределах этого квадрата широты / долготы.
С индексом широты и долготы в поле база данных запрос
WHERE MyLat >= @MinLat AND MyLat <= @MaxLat AND MyLong >= @MinLong AND MyLong <= @MaxLong
должен быть очень эффективным
(обратите внимание, что я не знаю конкретно MySQL, только MS SQL)
Вы можете создать для своей таблицы индекс SPATIAL
, чтобы ускорить поиск.
Для этого добавьте в свою таблицу столбец POINT
:
ALTER TABLE restaurant ADD coords POINT NOT NULL;
CREATE SPATIAL INDEX sx_restaurant_coords ON restaurant (coords);
SELECT *
FROM restaurant
WHERE MBRContains(coords, LineString(Point(583734 - 1609, 4507223 - 1609), Point(583734 + 1609, 4507223 + 1609))
AND GLength(LineString(Point(583734, 4507223), coords)) <= 1609
Вам следует сохранить координаты
как UTM
координаты в одной зоне.
Если ваши данные находятся в базе данных SQL-сервера, вы можете использовать это:
CREATE PROC up_FindZipCodesWithinRadius
@ZipCode char(5) ,
@GivenMileRadius int
AS
SET NOCOUNT ON
DECLARE @lat1 float,
@long1 float
SELECT @lat1= latitude,
@long1 = longitude
FROM ZipSource
WHERE zipcode = @ZipCode
SELECT ZipCode ,DistanceInMiles
FROM
(
SELECT ZipCode,3958.75 * ( Atan(Sqrt(1 - power(((Sin(@Lat1/57.2958) * Sin(latitude/57.2958)) +
(Cos(@Lat1/57.2958) * Cos(latitude/57.2958) * Cos((longitude/57.2958) - (@Long1/57.2958)))), 2)) /
((Sin(@Lat1/57.2958) * Sin(latitude/57.2958)) + (Cos(@Lat1/57.2958) * Cos(latitude/57.2958) *
Cos((longitude/57.2958) - (@Long1/57.2958)))))) as DistanceInMiles
FROM ZipSource
) a
WHERE a.DistanceInMiles <= @GivenMileRadius
--AND ZipCode <> @ZipCode
ORDER BY DistanceInMiles
GO
EXEC up_FindZipCodesWithinRadius '35085',20
GO
DROP PROC up_FindZipCodesWithinRadius
Используйте функцию, например, ту , которую я разместил здесь .
Затем запросите ваши рестораны, например, чтобы получить все в радиусе 5 миль
select * from restaurants
where dbo.udf_Haversine(latitude, longitude, @lat, @long) < 5
Это отлично работает с данными почтового индекса.