sql >> Database >  >> RDS >> Sqlserver

Haal de dichtstbijzijnde lengte- en breedtegraad uit de MSSQL-databasetabel?

Laten we eens kijken naar een eenvoudig voorbeeld van het gebruik van de STDistance functie in SQL Server 2008 (en later).

Ik ga SQL Server vertellen dat ik in Londen ben, en ik wil zien hoe ver al mijn kantoren zijn verwijderd. Dit zijn de resultaten die ik wil dat SQL Server me geeft:

Eerst hebben we enkele voorbeeldgegevens nodig. We maken een tabel met enkele locaties van Microsoft-kantoren en we slaan hun lengte- en breedtegraad op in een geography veld.

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())

Stel nu dat we in Londen waren. Zo maakt u een geography waarde uit de lengte- en breedtegraadwaarden van Londen:

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) + ')';

En tot slot, laten we eens kijken hoe ver elk van onze kantoren is.

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

En dit geeft ons de resultaten waar we op hoopten.

Uiteraard kunt u een TOP(1) . invoeren als je alleen de dichtstbijzijnde . wilt zien kantoor.

Cool, hé ?

Er is maar één addertje onder het gras. Als je veel geography hebt punten om mee te vergelijken, de prestaties zijn niet geweldig, zelfs niet als u een SPATIAL INDEX toevoegt aan dat databaseveld.

Ik heb een punt getest tegen een tabel van 330.000 geography punten. Met behulp van de hier getoonde code vond het het dichtstbijzijnde punt in ongeveer 8 seconden .

Toen ik mijn tabel aanpaste om de lengte- en breedtegraadwaarden op te slaan, en de [dbo].[fnCalcDistanceMiles] gebruikte functie van dit StackOverflow-artikel, vond het het dichtstbijzijnde punt in ongeveer 3 seconden .

Maar...

Alle voorbeelden van "afstand tussen twee punten" die ik op internet vond, gebruikten de SQL Server STDistance functie, of wiskundige formules met de (CPU-intensieve) cos, sin en tan functies.

Een snellere oplossing was om terug te reizen in de tijd naar de middelbare school en te onthouden hoe Pythagoras de afstand tussen twee punten berekende.

Stel dat we de afstand tussen Londen en Parijs willen weten.

En hier is mijn SQL Server-functie:

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

Onthoud dat deze functie geen waarde retourneert in mijlen, kilometers, enz... het vergelijkt alleen de lengte- en breedtegraadwaarden. En Pythagoras is bedoeld om in 2D te worden gebruikt, en niet om punten op een ronde planeet te vergelijken!

In mijn tests vond het echter het dichtstbijzijnde punt binnen 1 seconde , en produceerde dezelfde resultaten als het gebruik van SQL Server's STDistance functie.

Gebruik deze functie dus gerust voor het vergelijken van relatieve afstanden , maar gebruik deze functie niet als u de werkelijke afstand zelf nodig heeft.

Ik hoop dat dit allemaal helpt.



  1. Wijzigingsmelding Oracle Database

  2. Hoe u alle tabellen met identiteitskolom in SQL Server-database kunt vinden - SQL Server / T-SQL-zelfstudiedeel 45

  3. PostgreSQL breedtegraad lengtegraad query

  4. 11gR2 Compressie Adviseur =Kwaad