Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Lấy kinh độ và vĩ độ gần nhất từ ​​bảng cơ sở dữ liệu MSSQL?

Hãy xem một ví dụ đơn giản về việc sử dụng STDistance trong SQL Server 2008 (và mới hơn).

Tôi sẽ nói với SQL Server rằng tôi đang ở London và tôi muốn xem khoảng cách của từng văn phòng của tôi. Đây là kết quả mà tôi muốn SQL Server cung cấp cho tôi:

Đầu tiên, chúng tôi sẽ cần một số dữ liệu mẫu. Chúng tôi sẽ tạo một bảng chứa một vài vị trí của các văn phòng Microsoft và chúng tôi sẽ lưu trữ các giá trị kinh độ &vĩ độ của chúng trong một geography trường.

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

Bây giờ, giả sử chúng tôi đang ở London. Đây là cách tạo geography giá trị ngoài các giá trị kinh độ &vĩ độ của Luân Đôn:

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

Và cuối cùng, hãy xem mỗi văn phòng của chúng ta cách nhau bao xa.

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

Và điều này mang lại cho chúng tôi kết quả mà chúng tôi mong đợi.

Rõ ràng, bạn có thể trượt TOP(1) nếu bạn chỉ muốn xem gần nhất văn phòng.

Hay quá, này?

Chỉ có một sự cố. Khi bạn có nhiều geography điểm để so sánh, hiệu suất không xuất sắc, ngay cả khi bạn thêm CHỈ SỐ SPATIAL trên trường cơ sở dữ liệu đó.

Tôi đã kiểm tra một điểm dựa trên bảng 330.000 geography điểm. Sử dụng mã hiển thị ở đây, nó tìm thấy điểm gần nhất trong khoảng 8 giây .

Khi tôi sửa đổi bảng của mình để lưu trữ các giá trị kinh độ và vĩ độ, đồng thời sử dụng [dbo].[fnCalcDistanceMiles] từ bài viết StackOverflow này, nó đã tìm thấy điểm gần nhất trong khoảng 3 giây .

Tuy nhiên ...

Tất cả các mẫu "khoảng cách giữa hai điểm" mà tôi tìm thấy trên internet đều sử dụng SQL Server STDistance hàm hoặc các công thức toán học liên quan đến các hàm cos, sin và tan (sử dụng nhiều CPU).

Một giải pháp nhanh hơn là quay ngược thời gian trở lại thời trung học và nhớ cách Pythagoras tính khoảng cách giữa hai điểm.

Giả sử chúng tôi muốn biết khoảng cách giữa London và Paris.

Và đây là hàm SQL Server của tôi:

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

Bây giờ, hãy nhớ rằng hàm này không trả về giá trị theo dặm, km, v.v. ... mà chỉ là so sánh các giá trị kinh độ &vĩ độ. Và Pythagoras được dùng trong 2D chứ không phải so sánh các điểm trên một hành tinh tròn!

Tuy nhiên, trong các thử nghiệm của tôi, nó đã tìm thấy điểm gần nhất trong vòng 1 giây và tạo ra kết quả tương tự như khi sử dụng STDistance của SQL Server chức năng.

Vì vậy, vui lòng sử dụng chức năng này để so sánh khoảng cách tương đối , nhưng không sử dụng chức năng này nếu bạn cần khoảng cách thực tế.

Hy vọng tất cả điều này sẽ hữu ích.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thay đổi chênh lệch múi giờ trên giá trị datetimeoffset trong SQL Server (T-SQL)

  2. Cách kiểm tra xem một cột được tính toán có "Cố định" trong SQL Server hay không

  3. Cách SCHEMA_NAME () hoạt động trong SQL Server

  4. Cách thêm ràng buộc khóa ngoại vào bảng hiện có trong SQL Server (T-SQL)

  5. SQL Server RAISERROR là gì?