Kommer du ihåg Pythagoras?
$sql = "SELECT * FROM table
WHERE lon BETWEEN '$minLon' AND '$maxLon'
AND lat BETWEEN '$minLat' AND '$maxLat'
ORDER BY (POW((lon-$lon),2) + POW((lat-$lat),2))";
Tekniskt sett är det kvadraten på avståndet istället för det faktiska avståndet, men eftersom du bara använder det för sortering spelar det ingen roll.
Detta använder formeln för plana avstånd, som bör vara bra över små avstånd.
MEN:
Om du vill vara mer exakt eller använda längre avstånd, använd denna formel för stora cirkelavstånd i radianer :
dist = acos[ sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lng1-lng2) ]
(För att få avståndet i verkliga enheter istället för radianer, multiplicera det med jordens radie. Det är dock inte nödvändigt för beställningsändamål.)
Latitud och longitud antas av MySQL-beräkningsmotorn vara i radianer, så om det är lagrat i grader (och det är det förmodligen), måste du multiplicera varje värde med pi/180, ungefär 0,01745:
$sf = 3.14159 / 180; // scaling factor
$sql = "SELECT * FROM table
WHERE lon BETWEEN '$minLon' AND '$maxLon'
AND lat BETWEEN '$minLat' AND '$maxLat'
ORDER BY ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))";
eller till och med:
$sf = 3.14159 / 180; // scaling factor
$er = 6350; // earth radius in miles, approximate
$mr = 100; // max radius
$sql = "SELECT * FROM table
WHERE $mr >= $er * ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))
ORDER BY ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))";