sql >> Base de Datos >  >> RDS >> Sqlserver

Tipo de datos de geografía de SQL Server punto más cercano en línea

Puedes almacenar tus objetos en una GEOGRAPHY columna y crea un SPATIAL INDEX sobre esta columna.

Desafortunadamente, SQL Server implementa índices espaciales colocando mosaicos en la superficie y almacenando los identificadores de mosaicos en un B-Tree simple índice, tan simple ORDER BY STDistance no funcionará (bueno, funcionará pero no usará el índice).

En su lugar, tendrás que hacer una consulta similar a esta:

DECLARE @mypoint GEOGRAPHY
SET @mypoint = geography::STGeomFromText('POINT(@mylat, @mylon)', 4326);

WITH    num (distance) AS
        (
        SELECT  1000
        UNION ALL
        SELECT  distance + 1000
        FROM    num
        WHERE   distance <= 50000
        )
SELECT  TOP 1 m.*
FROM    num
CROSS APPLY
        (
        SELECT  TOP 1 *
        FROM    mytable
        WHERE   myroad.STDistance(@mypoint) <= distance
        ORDER BY
                STDistance(@mypoint)
        ) m

De esta forma, SQL Server primero buscará carreteras dentro de 1 kilómetro desde su punto, luego dentro de 2 kilómetros, etc., cada vez usando el índice.

Actualización:

Si tiene varios puntos en una tabla y desea encontrar el punto más cercano para cada uno de ellos:

WITH    num (distance) AS
        (
        SELECT  1000
        UNION ALL
        SELECT  distance + 1000
        FROM    num
        WHERE   distance <= 50000
        )
SELECT  mp.mypoint, m.*
FROM    @mypoints mp
CROSS APPLY
        (
        SELECT  TOP 1 m.*
        FROM    num
        CROSS APPLY
                (
                SELECT  TOP 1 *
                FROM    mytable
                WHERE   myroad.STDistance(@mypoint) <= distance
                ORDER BY
                        STDistance(@mypoint)
                ) m
        ) m