Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Получавате най-близката дължина и ширина от таблицата на базата данни на MSSQL?

Нека разгледаме прост пример за използване на STDistance функция в SQL Server 2008 (и по-нова версия).

Ще кажа на SQL Server, че съм в Лондон и искам да видя колко далеч е всеки един от моите офиси. Ето резултатите, които искам да ми даде SQL Server:

Първо, ще ни трябват някои примерни данни. Ще създадем таблица, съдържаща няколко местоположения на офиси на Microsoft и ще съхраняваме техните стойности за дължина и ширина в geography поле.

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

Сега, да предположим, че сме в Лондон. Ето как да направите geography стойност извън стойностите на географската дължина и ширина на Лондон:

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

И накрая, нека видим колко далеч е всеки един от нашите офиси.

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

И това ни дава резултатите, на които се надявахме.

Очевидно можете да въведете TOP(1) ако просто искате да видите най-близкия офис.

Страхотно, хей?

Има само една пречка. Когато имате много geography точки за сравнение, производителността не е брилянтна, дори ако добавите ПРОСТРАНСТВЕН ИНДЕКС към това поле на базата данни.

Тествах точка срещу таблица от 330 000 geography точки. Използвайки показания тук код, той намери най-близката точка за около 8 секунди .

Когато промених таблицата си, за да съхранявам стойностите за географска дължина и ширина, и използвах [dbo].[fnCalcDistanceMiles] функция от тази статия на StackOverflow, тя намери най-близката точка за около 3 секунди .

Въпреки това...

Всички проби за "разстояние между две точки", които намерих в интернет, използваха SQL Server STDistance функция или математически формули, включващи (интензивните на процесора) функции cos, sin и tan.

По-бързото решение беше да пътувате назад във времето до гимназията и да си спомните как Питагор е изчислил разстоянието между две точки.

Да предположим, че искаме да знаем разстоянието между Лондон и Париж.

И ето моята функция на SQL Server:

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

Сега, запомнете, че тази функция не връща стойност в мили, километри и т.н.... а просто сравнява стойностите за дължина и ширина. И Pythagoras е предназначен да се използва в 2D, а не да се сравняват точки на кръгла планета!

При моите тестове обаче откри най-близката точка в рамките на 1 секунда и даде същите резултати като използването на STDistance на SQL Server функция.

Така че, не се колебайте да използвате тази функция за сравняване на относителни разстояния , но не използвайте тази функция, ако имате нужда от самото действително разстояние.

Надявам се всичко това да помогне.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Групи за разговори на Sql Server Service Broker

  2. Има ли начин за достъп до стойността на предишния ред в оператор SELECT?

  3. Visual Studio:ContextSwitchDeadlock

  4. Какво е логически оператор И в SQL Server - SQL Server / TSQL урок, част 120

  5. Грешка на SQL Server 110:Има по-малко колони в израза INSERT от стойностите, посочени в клаузата VALUES.