sql >> Databasteknik >  >> RDS >> Mysql

Sorterar MySQL-fråga efter latitud/longitud

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))";


  1. SQLException:Ingen lämplig drivrutin hittades för jdbc:oracle:thin:@//localhost:1521/orcl

  2. SQLite Order By Date1530019888000

  3. Hur skapar jag en främmande nyckel i SQL Server?

  4. Flera rangordnar i en tabell