sql >> Database teknologi >  >> RDS >> Mysql

Sortering af MySQL-forespørgsel efter breddegrad/længdegrad

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

Teknisk set er det kvadratet af afstanden i stedet for den faktiske afstand, men da du bare bruger det til sortering, betyder det ikke noget.

Dette bruger den plane afstandsformel, som skal være god over små afstande.

DOG:

Hvis du vil være mere præcis eller bruge længere afstande, så brug denne formel for store cirkelafstande i radianer :

dist = acos[ sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lng1-lng2) ]

(For at få afstanden i reelle enheder i stedet for radianer skal du gange den med Jordens radius. Det er dog ikke nødvendigt for bestillingsformål.)

Bredde- og længdegrad antages af MySQL-beregningsmotoren at være i radianer, så hvis det er gemt i grader (og det er det sandsynligvis), bliver du nødt til at gange hver værdi med pi/180, cirka 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 endda:

$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. Nulstil MySQL root-adgangskoden ved hjælp af ALTER USER-sætning efter installation på Mac

  2. Udfør kun udskudt trigger én gang pr. række i PostgreSQL

  3. MySQL kill-processen er, at brugeren ikke har nok point PHP

  4. mysql indsæt race tilstand