Partilhar via


Consultar dados espaciais para o vizinho mais próximo

Aplica-se a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceEndpoint de análise SQL no Microsoft FabricArmazém no Microsoft FabricBase de dados SQL no Microsoft Fabric

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

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

Syntax

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 e ORDER BY as cláusulas são usadas para executar uma consulta vizinha mais próxima em colunas de dados espaciais. A cláusula ORDER BY contém uma chamada ao método STDistance() para o tipo de dados da coluna espacial. A TOP cláusula indica o número de objetos a serem retornados para a consulta.

Os seguintes requisitos devem ser atendidos para que uma consulta vizinha mais próxima use um índice espacial:

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

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

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

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

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

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

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

Warning

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

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

Exemplo 1

O exemplo de código a seguir mostra uma consulta vizinha mais próxima que pode usar um índice espacial. O exemplo usa a tabela Person.Address na base de dados de exemplo AdventureWorks2025.

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 vizinha mais próxima usa um índice espacial. Para obter mais informações sobre como criar índices espaciais, consulte Criar, modificar e descartar índices espaciais.

Exemplo 2

O exemplo de código a seguir mostra uma consulta vizinha mais próxima 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 WHERE cláusula que usa STDistance() em um formulário especificado na seção de sintaxe, portanto, a consulta não pode usar um índice espacial.