Compartir a través de


Consulta de datos espaciales para el vecino más cercano

Se aplica a: Sql Server Azure SQL Database Azure SQL Instancia administrada punto de conexión de SQL Analytics en Microsoft Fabric Warehouse en la base de datos SQL de Microsoft Fabric en Microsoft Fabric

Una consulta común que se usa con datos espaciales es la consulta vecina más cercana. Las consultas vecinas más cercanas se usan para buscar los objetos espaciales más cercanos a un objeto espacial específico. Por ejemplo, un localizador de tiendas para un sitio web a menudo debe encontrar las ubicaciones de almacén más cercanas a una ubicación del cliente.

Una consulta vecina más cercana se puede escribir en varios formatos de consulta válidos, pero para que la consulta vecina más cercana use un índice espacial, se debe usar la sintaxis siguiente.

Sintaxis

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 ]  
[ ; ]  

Consultas y índices espaciales vecinos más cercanos

En SQL Server, TOP las cláusulas y ORDER BY se usan para realizar una consulta de vecino más cercana en columnas de datos espaciales. La cláusula ORDER BY contiene una llamada al método STDistance() para el tipo de datos de columna espacial. La cláusula TOP indica el número de objetos que se va a devolver para la consulta.

Se deben cumplir los siguientes requisitos para que una consulta vecina más cercana use un índice espacial:

  1. Debe haber un índice espacial en una de las columnas espaciales y el método STDistance() debe utilizar esa columna en las cláusulas WHERE y ORDER BY.

  2. La cláusula TOP no puede contener una instrucción PERCENT.

  3. La cláusula WHERE debe contener un método STDistance().

  4. Si hay varios predicados en la cláusula WHERE, el predicado que contiene el método STDistance() debe estar conectado por una conjunción AND a los demás predicados. El método STDistance() no puede estar en una parte opcional de la cláusula WHERE.

  5. La primera expresión de la cláusula ORDER BY debe utilizar el método STDistance().

  6. El criterio de ordenación para la primera expresión STDistance() de la cláusula ORDER BY debe ser ASC.

  7. Todas las filas para las que STDistance devuelve NULL se deben filtrar.

Advertencia

Los métodos que toman tipos de datos geography o geometry como argumentos devolverán NULL si los SRID no son los mismos para los tipos.

Se recomienda usar las nuevas teselaciones de índices espaciales para los índices usados en las consultas vecinas más cercanas. Para obtener más información sobre las teselaciones de índices espaciales, consulte Datos espaciales.

Ejemplo 1

En el ejemplo de código siguiente se muestra una consulta de vecino más cercana que puede usar un índice espacial. El ejemplo utiliza la tabla Person.Address de la base de datos de ejemplo 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);  

Cree un índice espacial en la columna SpatialLocation para ver cómo una consulta vecina más cercana usa un índice espacial. Para obtener más información sobre cómo crear índices espaciales, vea Create, Modify, and Drop Spatial Indexes.

Ejemplo 2

En el ejemplo de código siguiente se muestra una consulta de vecino más cercana que no puede usar un í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 la consulta le falta una cláusula WHERE que utilice STDistance() en un formato especificado en la sección de sintaxis, por lo que la consulta no puede utilizar un índice espacial.