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

Den nächstgelegenen Längen- und Breitengrad aus der MSSQL-Datenbanktabelle abrufen?

Sehen wir uns ein einfaches Beispiel für die Verwendung von STDistance an Funktion in SQL Server 2008 (und höher).

Ich werde SQL Server mitteilen, dass ich in London bin, und ich möchte sehen, wie weit meine Büros entfernt sind. Hier sind die Ergebnisse, die SQL Server mir geben soll:

Zunächst benötigen wir einige Beispieldaten. Wir erstellen eine Tabelle mit einigen Standorten von Microsoft-Büros und speichern ihre Längen- und Breitengrade in einer geography Feld.

CREATE TABLE [Offices] (
    [Office_Id] [int] IDENTITY(1, 1) NOT NULL,
    [Office_Name] [nvarchar](200) NOT NULL,
    [Office_Location] [geography] NOT NULL,
    [Update_By] nvarchar(30) NULL,
    [Update_Time] [datetime]
) ON [PRIMARY]

GO

INSERT INTO [dbo].[Offices] VALUES ('Microsoft Zurich', 'POINT(8.590847 47.408860 )', 'mike', GetDate())
INSERT INTO [dbo].[Offices] VALUES ('Microsoft San Francisco', 'POINT(-122.403697 37.792062 )', 'mike', GetDate())
INSERT INTO [dbo].[Offices] VALUES ('Microsoft Paris', 'POINT(2.265509 48.833946)', 'mike', GetDate())
INSERT INTO [dbo].[Offices] VALUES ('Microsoft Sydney', 'POINT(151.138378 -33.796572)', 'mike', GetDate())
INSERT INTO [dbo].[Offices] VALUES ('Microsoft Dubai', 'POINT(55.286282 25.228850)', 'mike', GetDate())

Angenommen, wir wären in London. So erstellen Sie eine geography Wert aus Londons Längen- und Breitengradwerten:

DECLARE 
    @latitude numeric(12, 7),
    @longitude numeric(12, 7)

SET @latitude = 51.507351
SET @longitude = -0.127758

DECLARE @g geography = 'POINT(' + cast(@longitude as nvarchar) + ' ' + cast(@latitude as nvarchar) + ')';

Und schließlich sehen wir uns an, wie weit jedes unserer Büros entfernt ist.

SELECT [Office_Name], 
       cast([Office_Location].STDistance(@g) / 1609.344 as numeric(10, 1)) as 'Distance (in miles)' 
FROM [Offices]
ORDER BY 2 ASC

Und das liefert uns die erhofften Ergebnisse.

Offensichtlich könntest du ein TOP(1) hineinschlüpfen wenn Sie nur die Nächste sehen wollten Büro.

Cool, hallo ?

Es gibt nur einen Haken. Wenn Sie viel geography haben Vergleichspunkte, die Leistung ist nicht brillant, selbst wenn Sie diesem Datenbankfeld einen RÄUMLICHEN INDEX hinzufügen.

Ich habe einen Punkt gegen eine Tabelle mit 330.000 geography getestet Punkte. Mit dem hier gezeigten Code wurde der nächstgelegene Punkt in etwa 8 Sekunden gefunden .

Als ich meine Tabelle geändert habe, um die Längen- und Breitengrade zu speichern, und den [dbo].[fnCalcDistanceMiles] verwendet habe Funktion aus diesem StackOverflow-Artikel hat sie den nächstgelegenen Punkt in etwa 3 Sekunden gefunden .

Allerdings...

Alle Beispiele für "Entfernung zwischen zwei Punkten", die ich im Internet gefunden habe, verwendeten entweder den SQL Server STDistance Funktion oder mathematische Formeln mit den (CPU-intensiven) cos-, sin- und tan-Funktionen.

Eine schnellere Lösung wäre, in der Zeit zurück zur High School zu reisen und sich daran zu erinnern, wie Pythagoras die Entfernung zwischen zwei Punkten berechnet hat.

Angenommen, wir wollten die Entfernung zwischen London und Paris wissen.

Und hier ist meine SQL Server-Funktion:

CREATE FUNCTION [dbo].[uf_CalculateDistance] (@Lat1 decimal(8,4), @Long1 decimal(8,4), @Lat2 decimal(8,4), @Long2 decimal(8,4))
RETURNS decimal (8,4) AS
BEGIN
    DECLARE @d decimal(28,10)

    SET @d = sqrt(square(@[email protected]) + square(@[email protected]))

    RETURN @d
END

Denken Sie daran, dass diese Funktion keinen Wert in Meilen, Kilometern usw. zurückgibt. Sie vergleicht lediglich die Längen- und Breitengrade. Und Pythagoras soll in 2D verwendet werden und nicht zum Vergleichen von Punkten auf einem runden Planeten !

In meinen Tests fand es jedoch den nächstgelegenen Punkt innerhalb von 1 Sekunde , und erzeugte die gleichen Ergebnisse wie die Verwendung von STDistance von SQL Server Funktion.

Verwenden Sie diese Funktion also gerne zum Vergleichen von relativen Entfernungen , aber verwenden Sie diese Funktion nicht, wenn Sie die tatsächliche Entfernung selbst benötigen.

Hoffe das alles hilft.