Поделиться через


Запрос пространственных данных для ближайшего соседа

Распространенный запрос, используемый с пространственными данными, — это запрос ближайшего соседа. Запросы ближайшего соседа используются для поиска ближайших пространственных объектов к конкретному пространственному объекту. Например, локатор магазинов на веб-сайте часто должен находить ближайшие магазины к местоположению клиента.

Запрос ближайшего соседа можно записать в различных допустимых форматах запросов, но для использования пространственного индекса необходимо использовать следующий синтаксис.

Синтаксис

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

Ближайшие соседние запросы и пространственные индексы

В SQL Server используются TOP и ORDER BY в предложениях для выполнения запроса ближайшего соседа по столбцам пространственных данных. Предложение ORDER BY содержит вызов метода STDistance() для типа данных пространственного столбца. Предложение TOP задает количество возвращаемых запросом объектов.

Чтобы использовать пространственный индекс, необходимо выполнить следующие требования для запроса ближайшего соседа:

  1. В одном из пространственных столбцов должен иметься пространственный индекс, а метод STDistance() должен использовать этот столбец в предложениях WHERE и ORDER BY.

  2. Пункт TOP не может содержать оператор PERCENT.

  3. Предложение WHERE должно содержать метод STDistance().

  4. Если в предложении WHERE имеется несколько предикатов, то предикат, содержащий метод STDistance(), должен соединяться с другими предикатами условием AND. Метод STDistance() не может входить в необязательную часть предложения WHERE.

  5. Первое выражение в предложении ORDER BY должно вызывать метод STDistance().

  6. Порядок сортировки для первого выражения STDistance() в предложении ORDER BY должен быть ASC.

  7. Все строки, для которых STDistance возвращает NULL, должны исключаться фильтром.

Предупреждение

Методы, которые принимают в качестве аргументов типы данных geography или geometry, вернут NULL , если идентификаторы SRID для этих типов не совпадают.

Рекомендуется использовать новые пространственные индексы и тесселяции для индексов, применяемых в запросах ближайшего соседа. Дополнительные сведения об тесселяции пространственных индексов см. в разделе "Пространственные данные" (SQL Server).

Пример

В следующем примере кода показан запрос ближайшего соседа, который может использовать пространственный индекс. В примере используется 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, чтобы узнать, как запрос ближайшего соседа использует пространственный индекс. Дополнительные сведения о создании пространственных индексов см. в разделе Create, Modify, and Drop Spatial Indexes.

Пример

В следующем примере кода показан запрос ближайшего соседа, который не может использовать пространственный индекс.

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

В запросе отсутствует предложение WHERE, использующее STDistance() указанным в разделе синтаксиса образом, поэтому данный запрос не может использовать пространственный индекс.

См. также

Пространственные данные (SQL Server)