Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Tipo di dati Geografia di SQL Server il punto più vicino sulla linea

Puoi memorizzare i tuoi oggetti in una GEOGRAPHY colonna e creare un SPATIAL INDEX su questa colonna.

Sfortunatamente, SQL Server implementa gli indici spaziali affiancando la superficie e memorizzando gli identificatori delle tessere in un semplice B-Tree index, quindi semplice ORDER BY STDistance non funzionerà (beh, funzionerà ma non utilizzerà l'indice).

Dovrai invece fare una query simile a questa:

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

In questo modo, SQL Server cercherà prima le strade all'interno di 1 chilometro dal tuo punto, quindi entro 2 chilometri, ecc., utilizzando ogni volta l'indice.

Aggiornamento:

Se hai più punti in una tabella e vuoi trovare il punto più vicino per ciascuno di essi:

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