Mari kita lihat contoh sederhana menggunakan STDistance
fungsi di SQL Server 2008 (dan yang lebih baru).
Saya akan memberitahu SQL Server bahwa saya di London, dan saya ingin melihat seberapa jauh masing-masing kantor saya. Inilah hasil yang saya ingin SQL Server berikan kepada saya:
Pertama, kita memerlukan beberapa data sampel. Kami akan membuat tabel yang berisi beberapa lokasi kantor Microsoft, dan kami akan menyimpan nilai bujur &lintangnya dalam geography
lapangan.
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())
Sekarang, seandainya kita berada di London. Berikut cara membuat geography
nilai dari nilai bujur &lintang London:
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) + ')';
Dan terakhir, mari kita lihat seberapa jauh masing-masing kantor kita.
SELECT [Office_Name],
cast([Office_Location].STDistance(@g) / 1609.344 as numeric(10, 1)) as 'Distance (in miles)'
FROM [Offices]
ORDER BY 2 ASC
Dan ini memberi kami hasil yang kami harapkan.
Jelas, Anda bisa memasukkan TOP(1)
jika Anda hanya ingin melihat terdekat kantor.
Keren, kan?
Hanya ada satu halangan. Ketika Anda memiliki banyak geography
poin untuk dibandingkan, kinerjanya tidak brilian, bahkan jika Anda menambahkan INDEKS SPASIAL pada bidang basis data itu.
Saya menguji satu poin terhadap tabel 330.000 geography
poin. Menggunakan kode yang ditampilkan di sini, ia menemukan titik terdekat dalam waktu sekitar 8 detik .
Ketika saya memodifikasi tabel saya untuk menyimpan nilai bujur dan lintang, dan menggunakan [dbo].[fnCalcDistanceMiles]
fungsi dari artikel StackOverflow ini, ia menemukan titik terdekat dalam waktu sekitar 3 detik .
Namun...
Semua sampel "jarak antara dua titik" yang saya temukan di internet menggunakan STDistance
SQL Server fungsi, atau rumus matematika yang melibatkan fungsi cos, sin, dan tan (intensif CPU).
Solusi yang lebih cepat adalah kembali ke masa lalu ke sekolah menengah, dan ingat bagaimana Pythagoras menghitung jarak antara dua titik.
Misalkan kita ingin mengetahui jarak antara London dan Paris.
Dan inilah fungsi SQL Server saya:
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
Sekarang, ingat fungsi ini tidak mengembalikan nilai dalam mil, kilometer, dll... itu hanya membandingkan nilai bujur &lintang. Dan Pythagoras dimaksudkan untuk digunakan dalam 2D, dan tidak membandingkan titik di planet bulat !
Namun, dalam pengujian saya, ia menemukan titik terdekat dalam 1 detik , dan menghasilkan hasil yang sama seperti menggunakan STDistance
SQL SQL Server fungsi.
Jadi, jangan ragu untuk menggunakan fungsi ini untuk membandingkan jarak relatif , tetapi jangan gunakan fungsi ini jika Anda membutuhkan jarak sebenarnya.
Semoga semua ini membantu.