Compartilhar via


Consultar dados espaciais para o vizinho mais próximo

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Ponto de extremidade de análise de SQL no Microsoft Fabric Warehouse no Microsoft Fabric Banco de dados SQL no Microsoft Fabric

Uma consulta comum usada com dados espaciais é a consulta do vizinho mais próximo. As consultas de vizinhos mais próximos são usadas para localizar os objetos espaciais mais próximos de um objeto espacial específico. Por exemplo, um localizador de lojas para um site geralmente deve encontrar os locais de loja mais próximos de um local do cliente.

Uma consulta do vizinho mais próximo pode ser gravada em vários formatos de consulta válidos, mas para que a consulta do vizinho mais próximo use um índice espacial, a sintaxe a seguir deve ser usada.

Sintaxe

SELECT TOP ( number )  
        [ WITH TIES ]  
        [ * | expression ]   
        [, ...]  
    FROM spatial_table_reference, ...   
        [ WITH   
            (   
                [ INDEX ( index_ref ) ]   
                [ , SPATIAL_WINDOW_MAX_CELLS = <value>]   
                [ ,... ]   
            )   
        ]  
    WHERE   
        column_ref.STDistance ( @spatial_ object )   
            {   
                [ IS NOT NULL ] | [ < const ] | [ > const ]   
                | [ <= const ] | [ >= const ] | [ <> const ] ]   
            }  
            [ AND { other_predicate } ]   
    }  
    ORDER BY column_ref.STDistance ( @spatial_ object ) [ ,...n ]  
[ ; ]  

Consulta de vizinho mais próximo e índices espaciais

No SQL Server, TOP as cláusulas and ORDER BY são usadas para executar uma consulta de vizinho mais próximo em colunas de dados espaciais. A cláusula ORDER BY contém uma chamada ao método STDistance() para o tipo de dados de coluna espacial. A cláusula TOP indica o número de objetos a ser retornado para a consulta.

Os seguintes requisitos devem ser atendidos para que uma consulta do vizinho mais próximo use um índice espacial:

  1. Um índice espacial deve estar presente em uma das colunas espaciais e o método STDistance() deve usar essa coluna nas cláusulas WHERE e ORDER BY.

  2. A cláusula TOP não pode conter uma instrução PERCENT.

  3. A cláusula WHERE deve conter um método STDistance().

  4. Se houver vários predicados na cláusula WHERE, o predicado que contém o método STDistance() deve ser conectado por uma conjunção AND aos outros predicados. O método STDistance() não pode estar em uma parte opcional da cláusula WHERE.

  5. A primeira expressão na cláusula ORDER BY deve usar o método STDistance().

  6. A ordem de classificação para a primeira expressão STDistance() na cláusula ORDER BY deve ser ASC.

  7. Todas as linhas para as quais STDistance retorna NULL devem ser filtradas.

Aviso

Os métodos que usam tipos de dados geography ou geometry como argumentos retornarão NULL se os SRIDs não forem os mesmos para os tipos.

Recomenda-se que as novas mosaicas de índice espacial sejam usadas para índices usados em consultas de vizinho mais próximo. Para obter mais informações sobre mosaicos de índice espacial, consulte Dados espaciais.

Exemplo 1

O exemplo de código a seguir mostra uma consulta de vizinho mais próximo que pode usar um índice espacial. O exemplo usa a tabela Person.Address no banco de dados de amostra AdventureWorks2022.

USE AdventureWorks2022  
GO  
DECLARE @g geography = 'POINT(-121.626 47.8315)';  
SELECT TOP(7) SpatialLocation.ToString(), City FROM Person.Address
WHERE SpatialLocation.STDistance(@g) IS NOT NULL  
ORDER BY SpatialLocation.STDistance(@g);  

Crie um índice espacial na coluna SpatialLocation para ver como uma consulta de vizinho mais próximo usa um índice espacial. Para obter mais informações sobre como criar índices espaciais, consulte Create, Modify, and Drop Spatial Indexes.

Exemplo 2

O exemplo de código a seguir mostra uma consulta de vizinho mais próximo que não pode usar um índice espacial.

USE AdventureWorks2022  
GO  
DECLARE @g geography = 'POINT(-121.626 47.8315)';  
SELECT TOP(7) SpatialLocation.ToString(), City FROM Person.Address  
ORDER BY SpatialLocation.STDistance(@g);  

A consulta não tem uma cláusula WHERE que usa STDistance() em uma forma especificada na seção de sintaxe; portanto, a consulta não pode usar um índice espacial.