2013-03-14 4 views
0

Я осознал этот «глупый» пространственный запрос, чтобы найти все точки, которые лежат на расстоянии 5 км от центра. Исходный стол содержит + 150 тыс. Строк.Пространственный запрос SQL Server: где поведение «странно»

Вот запрос:

DECLARE @position geography = geography::Parse('POINT(9.123 45.123)') 
DECLARE @circle geography = @position.STBuffer(5000) -- A circle of 5Km of radius 

SELECT 
    g.Coordinate.STDistance(@position), g.Coordinate.Filter(@circle) 
FROM 
    [DB_NAME].[SCHEMA].[TABLE] AS g WITH (nolock) 
WHERE 
    g.Coordinate.Filter(@circle) = 1 

Я странно наблюдать, что условие WHERE не работает: на самом деле я получить даже +600 точки, где условие возвращает 0.

Любые предложения?

Ради ясности схемы таблицы была

[DB_NAME].[SCHEMA].[TABLE](Coordinate geography NOT NULL) 
+0

Предположительно, '@ Start_Position' означает' @ position'? –

+0

Кроме того, ['Фильтр'] (http://msdn.microsoft.com/en-gb/library/cc627367.aspx):« Этот метод не является детерминированным и не точным ». –

+0

@ Damien ... Дело в том, что Coordinate.Filter (@circle) возвращает 0 для некоторых точек (как я проверял), но условие WHERE оценивает значение TRUE. –

ответ

0

Official documentation состояния: «Возвращает 1, если география экземпляра потенциально пересекает другую географию экземпляра. Этот метод может привести к ложноположительному возврату, и точный результат может быть зависящим от плана. Возвращает точное значение 0 (истинных отрицательные обратного), если нет пересечения экземпляров географии не найдено. »

Так что я имею в виду, что 0 всегда хорошо, в то время как 1 может быть приближены (ИМХО такое поведение является абсолютно разумным)

Кстати наблюдение @Damien приведет меня просто обойти:

DECLARE @position geography = geography::Parse('POINT(9.123 45.123)') 
DECLARE @circle geography = @position.STBuffer(5000) -- A circle of 5Km of radius 

SELECT * FROM 
    (SELECT 
     g.Coordinate.Filter(@circle) filter, g.Coordinate Coord 
     FROM [DB_NAME].[SCHEMA].[TABLE] AS g WITH (nolock) 
    WHERE 
     g.Coordinate.Filter(@circle) = 1 
    ) t 
    WHERE t.filter = 1 

, который напоминает мне «Double Check Pattern» эзотерикой ... но в этом случае это ясно мотивация.

Один вопрос, который может быть более изучен, касается преобразования возвращаемого значения ... Много лет назад я наткнулся на аналогичную проблему, где на ферме серверов неявное преобразование логического tre в int привело к -1 (0xFFFFFFFF) вместо из 1 (0x00000001) ... COM возрастов ...

Смежные вопросы