为 Nearest Neighbor 查询空间数据

Nearest Neighbor 查询是用于空间数据的常用查询。 Nearest Neighbor 查询用于查找与特定的空间对象最接近的空间对象。 例如,网站的存储区定位器必须时常查找与客户位置最接近的存储区位置。

可以用多种有效查询格式编写 Nearest Neighbor 查询,但是要使 Nearest Neighbor 查询使用空间索引,则必须使用下面的语法。

语法

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

Nearest Neighbor 查询和空间索引

在 SQL Server 中, TOPORDER BY 子句用于对空间数据列执行最近邻居查询。 对于空间列数据类型,ORDER BY 子句包含对 STDistance() 方法的调用。 TOP 子句指示针对该查询要返回的对象数。

为了使 Nearest Neighbor 查询使用空间索引,必须满足以下要求:

  1. 空间索引必须存在于其中一个空间列上,并且 STDistance() 方法必须在 WHEREORDER BY 子句中使用该空间列。

  2. TOP 子句不能包含 PERCENT 语句。

  3. WHERE 子句必须包含 STDistance() 方法。

  4. 如果 WHERE 子句中有多个谓词,则必须使用 AND 连词将包含 STDistance() 方法的谓词连接到其他谓词。 STDistance() 方法不能是 WHERE 子句的可选部分。

  5. ORDER BY 子句中的第一个表达式必须使用 STDistance() 方法。

  6. ORDER BY 子句中第一个 STDistance() 表达式的排序顺序必须是 ASC

  7. 必须筛选掉 STDistance 返回 NULL 的所有行。

警告

geographygeometry 数据类型作为参数的方法将返回 NULL,前提是 SRID 对于这些数据类型不同。

建议将新的空间索引分割用于在 Nearest Neighbor 查询中使用的索引。 有关空间索引分割的详细信息,请参阅空间数据 (SQL Server)

示例

下面的代码示例显示可以使用空间索引的 Nearest Neighbor 查询。 该示例使用 Person.Address 数据库中的 AdventureWorks2012 表。

USE AdventureWorks2012  
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);  
  

在 SpatialLocation 列上创建一个空间索引,以便了解 Nearest Neighbor 查询如何使用空间索引。 有关创建空间索引的详细信息,请参阅 Create, Modify, and Drop Spatial Indexes

示例

下面的代码示例显示不能使用空间索引的 Nearest Neighbor 查询。

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

该查询缺少在语法部分中指定的窗体中使用 STDistance()WHERE 子句,因此它无法使用空间索引。

另请参阅

空间数据 (SQL Server)