mySQL दूरी खोज के लिए आपके पास एक बहुत अच्छा संदर्भ है।
Oracle स्थानिक सामान के बारे में भूल जाओ। बहुत अधिक कोड, बहुत अधिक जटिलता, पर्याप्त मूल्यवर्धन नहीं।
यहां एक प्रश्न है जो चाल करेगा। यह क़ानून मील में दूरियों का उपयोग करता है। संपादित करें यदि आप इसे उत्तरी या दक्षिणी ध्रुव पर किसी स्थान के लिए उपयोग करने का प्रयास करते हैं, तो यह डिवाइड-चेकिंग की कीमत पर mdarwin द्वारा उल्लिखित बग को ठीक करता है।
SELECT id, city, LATITUDE, LONGITUDE, distance
FROM
(
SELECT id,
city,
LATITUDE, LONGITUDE,
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
))
AS distance,
b.mydst
FROM Cities
JOIN (
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
)b ON (1 = 1)
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
)a
WHERE distance <= mydst
ORDER BY distance
अगर आप किलोमीटर में काम कर रहे हैं, तो mydst/69 को mydst/111.045 में बदलें और 3959 से 6371.4 करें। (1/69 मील को डिग्री में बदलता है; 3959 ग्रह की त्रिज्या के लिए एक मान है।)
अब, आप शायद इस बड़ी क्वेरी को "मैजिक ब्लैक बॉक्स" के रूप में उपयोग करने के लिए ललचाएंगे। मत करो! इसे समझना बहुत कठिन नहीं है, और यदि आप इसे समझते हैं तो आप बेहतर कार्य करने में सक्षम होंगे। यहाँ क्या हो रहा है।
यह क्लॉज उस चीज का दिल है जो क्वेरी को तेज बनाती है। यह आपके शहर तालिका को आपके द्वारा निर्दिष्ट स्थान तक आस-पास के शहरों के लिए खोजता है।
WHERE LATITUDE >= mylat -(mydst/69)
AND LATITUDE <= mylat +(mydst/69)
AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
इसके काम करने के लिए, आपको निश्चित रूप से अपने LATITUDE कॉलम पर एक इंडेक्स की आवश्यकता है। आपके LONGITUDE कॉलम पर एक इंडेक्स भी थोड़ी मदद करेगा। यह एक अनुमानित खोज करता है, उन पंक्तियों की तलाश करता है जो आपके बिंदु के पास पृथ्वी की सतह पर अर्ध-आयताकार पैच के भीतर हैं। यह बहुत से शहरों का चयन करता है, लेकिन बहुत अधिक नहीं।
यहां यह खंड आपको अपने परिणाम सेट से अतिरिक्त शहरों को समाप्त करने देता है:
WHERE distance <= mydst
यह क्लॉज हावर्सिन फॉर्मूला है जो प्रत्येक शहर और आपके बिंदु के बीच महान-वृत्त की दूरी की गणना करता है।
(3959 * ACOS(COS(RADIANS(LATITUDE))
* COS(RADIANS(mylat))
* COS(RADIANS(LONGITUDE) - RADIANS(mylng))
+ SIN(RADIANS(LATITUDE))
* SIN(RADIANS(mylat))
यह क्लॉज आपको अपनी बात, और अपनी त्रिज्या-सीमा दर्ज करने देता है, बस एक बार आपकी क्वेरी के लिए बाध्य चर के रूप में। यह मददगार है क्योंकि विभिन्न सूत्र उन चरों का कई बार उपयोग करते हैं।
SELECT :LAT AS mylat,
:LONG AS mylng,
:RADIUS_LIMIT AS mydst
FROM DUAL
बाकी क्वेरी बस चीजों को व्यवस्थित करती है ताकि आप दूरी के अनुसार चयन करें और ऑर्डर करें।
यहां एक और पूरी व्याख्या दी गई है:http://www.plumislandmedia.net /mysql/haversine-mysql-निकटतम-लोक/