Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server Geography-Datentyp Nächster Punkt auf der Linie

Sie können Ihre Objekte in einem GEOGRAPHY speichern Spalte und erstellen Sie einen SPATIAL INDEX über dieser Spalte.

Leider SQL Server implementiert räumliche Indizes durch Kacheln der Oberfläche und Speichern der Kachelkennungen in einem einfachen B-Tree Index, also einfach ORDER BY STDistance wird nicht funktionieren (na ja, es wird funktionieren, aber den Index nicht verwenden).

Stattdessen müssen Sie eine Abfrage ähnlich der folgenden durchführen:

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

Auf diese Weise SQL Server sucht zuerst nach Straßen innerhalb von 1 Kilometer von Ihrem Punkt entfernt, dann innerhalb von 2 Kilometer usw., jedes Mal mit dem Index.

Aktualisierung:

Wenn Sie mehrere Punkte in einer Tabelle haben und den nächstgelegenen Punkt für jeden von ihnen finden möchten:

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