Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

किसी स्थान की त्रिज्या के भीतर कुल बिंदुओं के लिए SQL क्वेरी

MySQL गुरु या नहीं, समस्या यह है कि जब तक आपको विभिन्न पंक्तियों को फ़िल्टर करने का कोई तरीका नहीं मिल जाता है, तब तक प्रत्येक बिंदु और प्रत्येक शहर के बीच की दूरी की गणना करने की आवश्यकता होती है...

दो सामान्य दृष्टिकोण हैं जो स्थिति में मदद कर सकते हैं

  • दूरी के फ़ॉर्मूले को आसान बनाएं
  • असंभावित उम्मीदवारों को किसी दिए गए शहर से 100k दायरे में फ़िल्टर करें

सुधार के इन दो मार्गों में जाने से पहले, आपको इस 100 मील की दूरी के संबंध में वांछित सटीकता के स्तर पर निर्णय लेना चाहिए, साथ ही आपको यह भी इंगित करना चाहिए कि कौन सा भौगोलिक क्षेत्र डेटाबेस द्वारा कवर किया गया है (क्या यह सिर्फ महाद्वीपीय यूएसए आदि है।

इसका कारण यह है कि जबकि अधिक सटीक संख्यात्मक रूप से, ग्रेट सर्कल फॉर्मूला, कम्प्यूटेशनल रूप से बहुत महंगा है। प्रदर्शन में सुधार का एक अन्य तरीका "ग्रिड निर्देशांक" को लेट/लॉन्ग निर्देशांकों को जोड़ने (या इसके बजाय) में संग्रहीत करना होगा।

संपादित करें :
एक सरल (लेकिन कम सटीक) सूत्र के बारे में कुछ विचार :
चूंकि हम अपेक्षाकृत छोटी दूरी के साथ काम कर रहे हैं, (और मैं 30 और 48 डिग्री अक्षांश उत्तर के बीच अनुमान लगा रहा हूं), हम यूक्लिडियन दूरी (या बेहतर अभी तक यूक्लिडियन दूरी के वर्ग) का उपयोग कर सकते हैं बजाय इसके कि अधिक जटिल गोलाकार त्रिकोणमिति सूत्र।
अपेक्षित सटीकता के स्तर के आधार पर, देशांतर की पूरी डिग्री के लिए रैखिक दूरी के लिए एक एकल पैरामीटर होना भी स्वीकार्य हो सकता है, माना क्षेत्र पर कुछ औसत लेना (लगभग 46 कहते हैं) कानून मील)। तब सूत्र बन जाएगा

  LatDegInMi = 69.0
  LongDegInMi = 46.0
  DistSquared = ((Lat1 - Lat2) * LatDegInMi) ^2 + ((Long1 - Long2) * LongDegInMi) ^2

पंक्तियों की संख्या को सीमित करने के लिए फ़िल्टर करने के लिए ग्रिड जानकारी वाले कॉलम के विचार पर दूरी की गणना के लिए माना जाता है।
सिस्टम में प्रत्येक "बिंदु", चाहे वह एक शहर हो, या कोई अन्य बिंदु (?वितरण स्थान, स्टोर स्थान... जो भी हो) को दो पूर्णांक निर्देशांक दिए गए हैं जो 25 मील के वर्ग को परिभाषित करते हैं * 25 मील जहां बिंदु है। संदर्भ बिंदु (किसी दिए गए शहर) से 100 मील के भीतर किसी भी बिंदु के निर्देशांक x दिशा में अधिकतम +/- 4 और y दिशा में +/- 4 होंगे। फिर हम निम्नलिखित के समान एक प्रश्न लिख सकते हैं

SELECT city, state, latitude, longitude, COUNT(*)
FROM zipcodes Z
JOIN points P 
  ON P.GridX IN (
    SELECT GridX - 4, GridX - 3, GridX - 2, GridX - 1, GridX, GridX +1, GridX + 2 GridX + 3, GridX +4
   FROM zipcode ZX WHERE Z.id = ZX.id)
  AND
   P.GridY IN (
    SELECT GridY - 4, GridY - 3, GridY - 2, GridY - 1, GridY, GridY +1, GridY + 2 GridY + 3, GridY +4
   FROM zipcode ZY WHERE Z.id = ZY.id)
WHERE P.Status = A
   AND ((Z.latitude - P.latitude) * LatDegInMi) ^2 
      + ((Z.longitude - P.longitude) * LongDegInMi) ^2 < (100^2)
GROUP BY city,state,latitude,longitude;

ध्यान दें कि LongDegInMi को या तो हार्डकोड किया जा सकता है (महाद्वीपीय संयुक्त राज्य अमेरिका के सभी स्थानों के लिए समान), या ज़िपकोड तालिका में संबंधित रिकॉर्ड से आ सकता है। इसी तरह, LatDegInMi को हार्डकोड किया जा सकता है (इसे अलग-अलग करने की आवश्यकता नहीं है, क्योंकि दूसरे के विपरीत यह अपेक्षाकृत स्थिर है)।

इसके तेज़ होने का कारण यह है कि ज़िप कोड तालिका और अंक तालिका के बीच कार्टेशियन उत्पाद में अधिकांश रिकॉर्ड के लिए, हम दूरी की गणना बिल्कुल नहीं करते हैं। हम उन्हें इंडेक्स वैल्यू (ग्रिडएक्स और ग्रिडवाई) के आधार पर खत्म करते हैं।

यह हमें इस सवाल पर लाता है कि कौन से SQL इंडेक्स का उत्पादन करना है। निश्चित रूप से, हम चाहते हैं:- ग्रिडएक्स + ग्रिडवाई + स्थिति (अंक तालिका पर) - ग्रिडवाई + ग्रिडएक्स + स्थिति (संभवतः) - शहर + राज्य + अक्षांश + देशांतर + ग्रिडएक्स + ग्रिड ज़िप कोड तालिका पर

ग्रिड का एक विकल्प किसी दिए गए शहर के अक्षांश और देशांतर के आधार पर अक्षांश और देशांतर की सीमाओं को "बाध्य" करना है, जिस पर हम विचार करेंगे। यानी जॉइन कंडीशन IN के बजाय एक रेंज बन जाती है:

JOIN points P 
  ON    P.latitude > (Z.Latitude - (100 / LatDegInMi)) 
    AND P.latitude < (Z.Latitude + (100 / LatDegInMi)) 
    AND P.longitude > (Z.longitude - (100 / LongDegInMi)) 
    AND P.longitude < (Z.longitude + (100 / LongDegInMi)) 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql डेटाबेस को Oracle में बदलें

  2. Laravel में जहां मौजूद नहीं है

  3. mysql, php और pdo का उपयोग करके असंवेदनशील केस का चयन करें

  4. MySQL FKs के लिए उचित नामकरण परंपरा क्या है?

  5. रेल (3+) में संग्रहीत कार्यविधियाँ अभी भी समर्थित क्यों नहीं हैं?