Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Pontos de consulta dentro de um determinado raio no MySQL


Para MySQL 5.7+

Dado que temos a seguinte tabela simples,
criar exemplo de tabela ( id bigint não nulo auto_increment chave primária, lnglat ponto não nulo); criar índice espacial example_lnglat no exemplo (lnglat); 

Com os seguintes dados simples,
inserir no exemplo (lnglat) valores(ponto(-2.990435, 53.409246)),(ponto(-2.990037, 53.409471)),(ponto(-2.989736, 53.409676)),(ponto(-2.989554, 53.409797) )),(ponto(-2,989350, 53,409906)),(ponto(-2,989178, 53,410085)),(ponto(-2,988739, 53,410309)),(ponto(-2,985874, 53,412656)),(ponto(-2,758019, 53,635928) )); 

Você obteria os pontos dentro de um determinado intervalo de outro ponto (nota:temos que pesquisar dentro de um polígono) com a seguinte combinação de funções st:
set @px =-2.990497;set @py =53.410943;set @range =150; -- meterset @rangeKm =@range / 1000;set @search_area =st_makeEnvelope ( point((@px + @rangeKm / 111), (@py + @rangeKm / 111)), point((@px - @rangeKm / 111) ), (@py - @rangeKm / 111)));selecione id, st_x(lnglat) lng, st_y(lnglat) lat, st_distance_sphere(point(@px, @py), lnglat) como a distância do exemplo onde st_contains(@ search_area, lnglat); 

Você deve ver algo assim como resultado:
3 -2.989736 53.409676 149.640842527762774 -2.98954 53.409797 141.9322327146618125 -2.98935 53.409906 138.116666666666125
Para referência de distância, se removermos a restrição, o resultado para o ponto de teste ficará assim:
1 -2.990435 53.409246 188.74211814575562 -2.990037 53.409471 166.494065091601583 -2.989736 53.409676 149.640842527762774 -2.989554 53.409797 141.932327146618125 -2.98935 53.409906 138.115162754025336 -2.989178 53.410085 129.402892895274737 -2.988739 53.410309 136.18755404982028 -2.985874 53.412656 360.785327320139639 -2.758019 53.635928 29360.27797292756 

Observação 1 :o campo é chamado lnglat, pois essa é a ordem correta se você pensar em pontos como (x, y) e também é a ordem em que a maioria das funções (como point) aceita o parâmetro

Observação 2 :você não pode realmente aproveitar os índices espaciais se usar círculos; observe também que o campo de ponto pode ser definido para aceitar nulo, mas os índices espaciais não podem indexá-lo se for anulável (todos os campos no índice devem ser não nulos).

Observação 3 :st_buffer é considerado (pela documentação) ruim para este caso de uso

Observação 4 :as funções acima (em particular st_distance_sphere) são documentadas como rápidas, mas não necessariamente super precisas; se seus dados forem super sensíveis a isso, adicione um pouco de espaço de manobra à pesquisa e faça alguns ajustes no conjunto de resultados