Konum sorguları
“Müşteriye en yakın mağaza”, “5 km içindeki kuryeler”, “hangi ilçede?” gibi sorular coğrafi (uzamsal) veri gerektirir. Basit mesafe hesabı düz SQL ile yapılabilir; ciddi işler için uzamsal tipler ve indeksler kullanılır.
Haversine: iki koordinat arasındaki mesafe
Dünyayı küre kabul ederek iki enlem/boylam arasındaki büyük daire mesafesi (km):
WITH sehir AS (
SELECT 'İstanbul' AS ad, 41.0082 AS enlem, 28.9784 AS boylam UNION ALL
SELECT 'Ankara', 39.9334, 32.8597 UNION ALL
SELECT 'İzmir', 38.4237, 27.1428 UNION ALL
SELECT 'Bursa', 40.1885, 29.0610 UNION ALL
SELECT 'Antalya', 36.8969, 30.7133
)
SELECT a.ad AS nereden, b.ad AS nereye,
ROUND(6371 * 2 * ASIN(SQRT(
POWER(SIN((b.enlem - a.enlem) * 0.0174532925 / 2), 2) +
COS(a.enlem * 0.0174532925) * COS(b.enlem * 0.0174532925) *
POWER(SIN((b.boylam - a.boylam) * 0.0174532925 / 2), 2))), 0) AS km
FROM sehir a JOIN sehir b ON a.ad = 'İstanbul' AND b.ad <> a.ad
ORDER BY km;
(0.0174532925 = π/180, dereceyi radyana çevirir; 6371 km Dünya'nın ortalama yarıçapı.)
Uzamsal tipler
-- PostgreSQL + PostGIS CREATE EXTENSION postgis; ALTER TABLE magaza ADD COLUMN konum geography(Point, 4326); UPDATE magaza SET konum = ST_SetSRID(ST_MakePoint(boylam, enlem), 4326)::geography; CREATE INDEX ix_magaza_konum ON magaza USING GIST (konum); -- 5 km içindeki mağazalar ve en yakın 3 SELECT ad, ST_Distance(konum, ST_MakePoint(28.98, 41.01)::geography) / 1000 AS km FROM magaza WHERE ST_DWithin(konum, ST_MakePoint(28.98, 41.01)::geography, 5000) ORDER BY konum <-> ST_MakePoint(28.98, 41.01)::geography LIMIT 3; -- SQL Server DECLARE @ben geography = geography::Point(41.01, 28.98, 4326); SELECT TOP (3) ad, konum.STDistance(@ben) / 1000 AS km FROM dbo.magaza ORDER BY konum.STDistance(@ben); -- BigQuery SELECT ad, ST_DISTANCE(konum, ST_GEOGPOINT(28.98, 41.01)) / 1000 AS km FROM anadolu.magaza WHERE ST_DWITHIN(konum, ST_GEOGPOINT(28.98, 41.01), 5000); -- MySQL 8 SELECT ad, ST_Distance_Sphere(konum, POINT(28.98, 41.01)) / 1000 AS km FROM magaza;
Sıra tuzağıFonksiyonların çoğu nokta için (boylam, enlem) sırası ister (x, y); SQL Server'ın
geography::Point fonksiyonu ise (enlem, boylam). Ters yazılan koordinatlar okyanusun ortasında nokta üretir.SRID 4326 = WGS 84 (GPS koordinatları). geography mesafeyi metre olarak küre üzerinde, geometry düzlemde hesaplar.