SQL क्वेरी के साथ निकटतम अक्षांश / देशांतर का पता लगाएं


173

मेरे पास अक्षांश और देशांतर हैं और मैं डेटाबेस से रिकॉर्ड खींचना चाहता हूं, जिसमें दूरी से निकटतम अक्षांश और देशांतर है, अगर वह दूरी निर्दिष्ट एक से अधिक हो जाती है, तो इसे पुनर्प्राप्त न करें।

तालिका संरचना:

id
latitude
longitude
place name
city
country
state
zip
sealevel

1
यह निकटता खोज प्रश्न के डुप्लिकेट की तरह है ।
डेरियस बेकन

1
MySQL (PDF लिंक) के साथ जियो (निकटता) खोज पर अलेक्जेंडर रुबिन द्वारा स्लाइड का एक सेट है
मार्टिज़न पीटरर्स

जवाबों:


209
SELECT latitude, longitude, SQRT(
    POW(69.1 * (latitude - [startlat]), 2) +
    POW(69.1 * ([startlng] - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;

जहां [स्टार्लेट] और [शुरुआत] वह स्थिति है जहां दूरी को मापना शुरू करना है।


49
बस एक प्रदर्शन नोट, यह सबसे अच्छा है कि दूरी के चर को कम न करें लेकिन इसके बजाय '25' परीक्षण मान को वर्गमूल करें ... बाद में यदि आप को दूरी दिखाने की आवश्यकता है तो पास किए गए परिणामों को sqrt करें
sradforth

9
मीटर में दूरी के लिए समान क्वेरी क्या होगी? (जो वर्तमान में मीलों दूर है, ठीक है?)
httpete

8
वह माप 25 क्या है?
स्टीफन डोनल

16
यहाँ स्पष्ट करने के लिए 69.1 मील से अक्षांश डिग्री के लिए रूपांतरण कारक है। ५ 57.३ लगभग १.3० / पाई है, इसीलिए इसे कोजेन फंक्शन के लिए डिग्रियों से रेडियन में परिवर्तित किया जाता है। 25 मील में खोज त्रिज्या है। दशमलव डिग्री और क़ानून मील का उपयोग करते समय उपयोग करने के लिए यह सूत्र है।
जॉन वैन्स

8
इसके अतिरिक्त, यह पृथ्वी की वक्रता को ध्यान में नहीं रखता है। यह लघु खोज रेडियो के लिए एक मुद्दा नहीं होगा। अन्यथा इवान और इगोर के उत्तर अधिक पूर्ण हैं।
जॉन वंस

63

Google का समाधान:

तालिका बनाना

जब आप MySQL टेबल बनाते हैं, तो आप lat और lng विशेषताओं पर विशेष ध्यान देना चाहते हैं। Google मानचित्र की वर्तमान ज़ूम क्षमताओं के साथ, आपको दशमलव के बाद केवल 6 अंकों की सटीकता चाहिए। अपनी मेज के लिए आवश्यक स्टोरेज स्पेस को कम से कम रखने के लिए, आप यह निर्दिष्ट कर सकते हैं कि लैट और लैंग की विशेषताएँ फ्लोट आकार (10,6) की हैं। यह फ़ील्ड को दशमलव के बाद 6 अंकों को संग्रहीत करने देगा, साथ ही दशमलव से पहले 4 अंकों तक, जैसे -123.456789 डिग्री। आपकी तालिका में प्राथमिक कुंजी के रूप में सेवा करने के लिए एक आईडी विशेषता भी होनी चाहिए।

CREATE TABLE `markers` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `name` VARCHAR( 60 ) NOT NULL ,
  `address` VARCHAR( 80 ) NOT NULL ,
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;

टेबल को आबाद करना

तालिका बनाने के बाद, यह डेटा के साथ इसे आबाद करने का समय है। नीचे दिया गया नमूना डेटा संयुक्त राज्य भर में बिखरे हुए लगभग 180 पिज्जा के लिए है। PhpMyAdmin में, आप CSV (अल्पविराम से अलग किए गए मान) सहित विभिन्न फ़ाइल स्वरूपों को आयात करने के लिए आयात टैब का उपयोग कर सकते हैं। Microsoft Excel और Google स्प्रेडशीट दोनों CSV प्रारूप में निर्यात करते हैं, ताकि आप CSV फ़ाइलों को निर्यात / आयात करके आसानी से स्प्रेडशीट से MySQL तालिकाओं में डेटा स्थानांतरित कर सकें।

INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Frankie Johnnie & Luigo Too','939 W El Camino Real, Mountain View, CA','37.386339','-122.085823');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Amici\'s East Coast Pizzeria','790 Castro St, Mountain View, CA','37.38714','-122.083235');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Kapp\'s Pizza Bar & Grill','191 Castro St, Mountain View, CA','37.393885','-122.078916');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Round Table Pizza: Mountain View','570 N Shoreline Blvd, Mountain View, CA','37.402653','-122.079354');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Tony & Alba\'s Pizza & Pasta','619 Escuela Ave, Mountain View, CA','37.394011','-122.095528');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Oregano\'s Wood-Fired Pizza','4546 El Camino Real, Los Altos, CA','37.401724','-122.114646');

MySQL के साथ स्थान खोजना

अपने मार्कर तालिका के स्थानों को खोजने के लिए जो किसी दिए गए अक्षांश / देशांतर की एक निश्चित त्रिज्या दूरी के भीतर हैं, आप हावरसाइन सूत्र के आधार पर एक चयन कथन का उपयोग कर सकते हैं। एक क्षेत्र पर निर्देशांक के दो जोड़े के बीच महान-सर्कल की दूरी की गणना के लिए हैवरसाइन सूत्र का आमतौर पर उपयोग किया जाता है। विकिपीडिया द्वारा एक गहराई से गणितीय व्याख्या दी गई है और सूत्र की अच्छी चर्चा है क्योंकि यह प्रोग्रामिंग से संबंधित है जो चल प्रकार की साइट पर है।

यहां SQL स्टेटमेंट है जो निकटतम 20 स्थानों को ढूंढेगा जो कि 25 मील के दायरे में 37, -122 में समन्वय करते हैं। यह उस पंक्ति के अक्षांश / देशांतर और लक्ष्य अक्षांश / देशांतर के आधार पर दूरी की गणना करता है, और फिर केवल उन पंक्तियों के लिए पूछता है जहाँ दूरी का मान 25 से कम है, पूरी क्वेरी को दूरी से आदेश देता है, और इसे 20 परिणामों तक सीमित करता है। मील के बजाय किलोमीटर से खोजने के लिए 3959 को 6371 से बदलें।

SELECT 
id, 
(
   3959 *
   acos(cos(radians(37)) * 
   cos(radians(lat)) * 
   cos(radians(lng) - 
   radians(-122)) + 
   sin(radians(37)) * 
   sin(radians(lat )))
) AS distance 
FROM markers 
HAVING distance < 28 
ORDER BY distance LIMIT 0, 20;

यह एक 28 मील से कम दूरी में अक्षांश और देशांतर का पता लगाना है।

एक और 28 और 29 मील की दूरी के बीच उन्हें खोजने के लिए है:

SELECT 
id, 
(
   3959 *
   acos(cos(radians(37)) * 
   cos(radians(lat)) * 
   cos(radians(lng) - 
   radians(-122)) + 
   sin(radians(37)) * 
   sin(radians(lat )))
) AS distance 
FROM markers 
HAVING distance < 29 and distance > 28 
ORDER BY distance LIMIT 0, 20;

https://developers.google.com/maps/articles/phpsqlsearch_v3#creating-the-map


1
क्या ऐसा होना चाहिए HAVING distance < 25जैसा कि हम 25 मील के दायरे में स्थानों को क्वेरी कर रहे हैं?
विटालि एलेनहॉट

यह> 25 होना चाहिए, फिर यह सभी रिकॉर्ड्स को
खोजेगा

क्या आप सुनिश्चित हैं @vidurpunj के बारे में> 25?
अमरानुर रहमान

मैं का उपयोग कर sql क्वेरी की कोशिश की: दूरी <25 लेकिन कोई परिणाम नहीं मिला .. के रूप में नमूना मार्करों दूरी सभी 25 से ऊपर हैं ...
इब्राहिमशाही

37, -122 समन्वय है, क्या यह स्थिति के लिए अक्षांश और देशांतर है जहां से हमें दूरी खोजने की आवश्यकता है?
प्रसोभ.कॉलट्टू

28

यहाँ PHP में कार्यान्वित मेरा पूरा समाधान है।

यह समाधान http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL में प्रस्तुत किए गए हैवरसाइन फॉर्मूला का उपयोग करता है ।

यह ध्यान दिया जाना चाहिए कि हावरसाइन सूत्र ध्रुवों के चारों ओर कमजोरियों का अनुभव करता है। यह उत्तर दिखाता है कि इसके चारों ओर प्राप्त करने के लिए विन्सेन्टी ग्रेट सर्कल डिस्टेंस फार्मूला को कैसे लागू किया जाए , हालाँकि मैंने सिर्फ हैवरसाइन का उपयोग करना चुना क्योंकि यह मेरे उद्देश्यों के लिए पर्याप्त है।

मैं अक्षांश (10,8) के रूप में अक्षांश और DECIMAL (11,8) के रूप में देशांतर का भंडारण कर रहा हूं। उम्मीद है कि यह मदद करता है!

showClosest.php

<?PHP
/**
 * Use the Haversine Formula to display the 100 closest matches to $origLat, $origLon
 * Only search the MySQL table $tableName for matches within a 10 mile ($dist) radius.
 */
include("./assets/db/db.php"); // Include database connection function
$db = new database(); // Initiate a new MySQL connection
$tableName = "db.table";
$origLat = 42.1365;
$origLon = -71.7559;
$dist = 10; // This is the maximum distance (in miles) away from $origLat, $origLon in which to search
$query = "SELECT name, latitude, longitude, 3956 * 2 * 
          ASIN(SQRT( POWER(SIN(($origLat - latitude)*pi()/180/2),2)
          +COS($origLat*pi()/180 )*COS(latitude*pi()/180)
          *POWER(SIN(($origLon-longitude)*pi()/180/2),2))) 
          as distance FROM $tableName WHERE 
          longitude between ($origLon-$dist/cos(radians($origLat))*69) 
          and ($origLon+$dist/cos(radians($origLat))*69) 
          and latitude between ($origLat-($dist/69)) 
          and ($origLat+($dist/69)) 
          having distance < $dist ORDER BY distance limit 100"; 
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result)) {
    echo $row['name']." > ".$row['distance']."<BR>";
}
mysql_close($db);
?>

./assets/db/db.php

<?PHP
/**
 * Class to initiate a new MySQL connection based on $dbInfo settings found in dbSettings.php
 *
 * @example $db = new database(); // Initiate a new database connection
 * @example mysql_close($db); // close the connection
 */
class database{
    protected $databaseLink;
    function __construct(){
        include "dbSettings.php";
        $this->database = $dbInfo['host'];
        $this->mysql_user = $dbInfo['user'];
        $this->mysql_pass = $dbInfo['pass'];
        $this->openConnection();
        return $this->get_link();
    }
    function openConnection(){
    $this->databaseLink = mysql_connect($this->database, $this->mysql_user, $this->mysql_pass);
    }

    function get_link(){
    return $this->databaseLink;
    }
}
?>

./assets/db/dbSettings.php

<?php
$dbInfo = array(
    'host'      => "localhost",
    'user'      => "root",
    'pass'      => "password"
);
?>

उपरोक्त पोस्ट किए गए "जियो-डिस्टेंस-सर्च-विथ-मायक्यूएस" के रूप में सुझाए गए MySQL संग्रहित प्रक्रिया का उपयोग करके प्रदर्शन को बढ़ाना संभव हो सकता है।

मेरे पास ~ 17,000 स्थानों का एक डेटाबेस है और क्वेरी निष्पादन का समय 0.054 सेकंड है।


मैं किमी या मीटर में दूरी कैसे प्राप्त कर सकता हूं? सादर!
केमिटैक्सिस

2
मील * 1.609344 = किमी
सिनान

2
चेतावनी। एक्सेलेंट समाधान, लेकिन इसमें एक बग है। सभी को absहटा दिया जाना चाहिए। डिग्रियों से रेडियन में परिवर्तित होने पर एब्स वैल्यू लेने की कोई आवश्यकता नहीं है, और यदि आपने किया भी है, तो आप इसे केवल एक अक्षांश के लिए कर रहे हैं। कृपया इसे संपादित करें ताकि यह बग को ठीक करे।
चांगो

1
और जो कोई भी मीटर में यह चाहता है: 3956 मील से किलोमीटर में परिवर्तित करें: पृथ्वी की त्रिज्या; 69 मील से किलोमीटर में परिवर्तित करें: किमी में 1 डिग्री अक्षांश की aproxímate लंबाई; और किलोमीटर में दूरी इनपुट करें।
चेंजो

1
और (उपरोक्त टिप्पणी में यह भूल गए) के 69साथ प्रतिस्थापित करें111,044736
reaket

24

बस अगर तुम मेरी तरह आलसी हो, तो यहाँ इस और एसओ पर अन्य उत्तरों से एक समाधान मिला है।

set @orig_lat=37.46; 
set @orig_long=-122.25; 
set @bounding_distance=1;

SELECT
*
,((ACOS(SIN(@orig_lat * PI() / 180) * SIN(`lat` * PI() / 180) + COS(@orig_lat * PI() / 180) * COS(`lat` * PI() / 180) * COS((@orig_long - `long`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS `distance` 
FROM `cities` 
WHERE
(
  `lat` BETWEEN (@orig_lat - @bounding_distance) AND (@orig_lat + @bounding_distance)
  AND `long` BETWEEN (@orig_long - @bounding_distance) AND (@orig_long + @bounding_distance)
)
ORDER BY `distance` ASC
limit 25;

1
वास्तव में क्या bounding_distanceदर्शाता है? क्या यह मान एक मील राशि तक परिणामों को सीमित करता है? तो इस मामले में यह 1 मील के भीतर परिणाम लौटाएगा?
जेम्स

1
@ बाउंडिंग_डिस्टेंस यहां डिग्री में है, और इसका उपयोग प्रभावी खोज क्षेत्र को सीमित करके गणना को गति देने के लिए किया जाता है। उदाहरण के लिए, यदि आप जानते हैं कि आपका उपयोगकर्ता एक निश्चित शहर में है, और आप जानते हैं कि आपके पास उस शहर के भीतर कुछ बिंदु हैं, तो आप सुरक्षित रूप से अपनी सीमा को कुछ डिग्री पर सेट कर सकते हैं।
इवान

1
यह किस भौगोलिक दूरी का सूत्र है?
bbodenmiller

12

आसान वाला ;)

SELECT * FROM `WAYPOINTS` W ORDER BY
ABS(ABS(W.`LATITUDE`-53.63) +
ABS(W.`LONGITUDE`-9.9)) ASC LIMIT 30;

बस अपने आवश्यक के साथ निर्देशांक बदलें। मूल्यों को दोहरे के रूप में संग्रहीत किया जाना है। यह एक कार्यशील MySQL 5.x उदाहरण है।

चियर्स


2
पता नहीं क्यों अपवोट, ओपी कुछ दूरी तक सीमित और ऑर्डर करना चाहता है, 30 तक सीमित नहीं है और इसके द्वारा ऑर्डर करता हैdx+dy
ओकम

3
इसने मेरे लिए यह किया। यह ओपी नहीं चाहता था, लेकिन यह वही है जो मैं चाहता था, इसलिए उत्तर देने के लिए धन्यवाद! :)
वेबमास्टर जी

सबसे बाहरी ABS () पर्याप्त है।
डॅज़ोना

6

यह कोशिश करो, यह प्रदान किए गए निर्देशांक (50 किमी के भीतर) के निकटतम बिंदुओं को दिखाता है। यह पूरी तरह से काम करता है:

SELECT m.name,
    m.lat, m.lon,
    p.distance_unit
             * DEGREES(ACOS(COS(RADIANS(p.latpoint))
             * COS(RADIANS(m.lat))
             * COS(RADIANS(p.longpoint) - RADIANS(m.lon))
             + SIN(RADIANS(p.latpoint))
             * SIN(RADIANS(m.lat)))) AS distance_in_km
FROM <table_name> AS m
JOIN (
      SELECT <userLat> AS latpoint, <userLon> AS longpoint,
             50.0 AS radius, 111.045 AS distance_unit
     ) AS p ON 1=1
WHERE m.lat
BETWEEN p.latpoint  - (p.radius / p.distance_unit)
    AND p.latpoint  + (p.radius / p.distance_unit)
    AND m.lon BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
    AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
ORDER BY distance_in_km

बस बदलो <table_name><userLat>तथा<userLon>

आप यहाँ इस समाधान के बारे में अधिक पढ़ सकते हैं: http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/


6

प्रश्न के मूल उत्तर अच्छे हैं, लेकिन mysql (MySQL 5.7.6 on) के नए संस्करण भू प्रश्नों का समर्थन करते हैं, इसलिए आप अब जटिल प्रश्नों को करने के बजाय कार्यक्षमता में निर्मित उपयोग कर सकते हैं।

अब आप कुछ ऐसा कर सकते हैं:

select *, ST_Distance_Sphere( point ('input_longitude', 'input_latitude'), 
                              point(longitude, latitude)) * .000621371192 
          as `distance_in_miles` 
  from `TableName`
having `distance_in_miles` <= 'input_max_distance'
 order by `distance_in_miles` asc

metersयदि आप KMमील के .0001बजाय उपयोग के बजाय चाहते हैं तो परिणाम वापस आ जाते हैं.000621371192

MySql डॉक्स यहाँ हैं


यदि संभव हो तो उत्तर में mysql संस्करण जोड़ें।
परिक्षित

ST_Distance_Sphereमेरे होस्ट की स्थापना ( mysql Ver 15.1 Distrib 10.2.23-MariaDB) में मौजूद नहीं है । मैं स्थानापन्न करने के लिए कहीं पढ़ता हूं ST_Distanceलेकिन दूरियां खत्म हो जाती हैं।
ashleedawg

@ashleedawg - संस्करण से, मुझे लगता है कि आप MariaDB का उपयोग कर रहे हैं, जो कि mysql का एक कांटा है। से इस बातचीत को यह लग रहा है MariaDB तरह लागू नहीं कियाST_Distance_Sphere
शर्मन

5

आप हेवेरिन फार्मूला जैसी चीजों की तलाश कर रहे हैं । यहाँ भी देखें ।

वहाँ अन्य लोग हैं, लेकिन यह सबसे अधिक उद्धृत है।

यदि आप कुछ और भी मजबूत देख रहे हैं, तो आप अपने डेटाबेस जीआईएस क्षमताओं को देखना चाहते हैं। वे कुछ शांत चीजों के लिए सक्षम हैं जैसे कि आपको बताना है कि क्या कोई बिंदु (शहर) किसी दिए गए बहुभुज (क्षेत्र, देश, महाद्वीप) के भीतर दिखाई देता है।


यह वास्तव में सबसे उद्धृत है, लेकिन कई लेख पुराने कंप्यूटिंग हार्डवेयर का उल्लेख करते हैं जब यह अन्य तरीकों का उपयोग करके गलत कंप्यूटिंग के बारे में बयान आता है। यह भी देखें चल-type.co.uk/scripts/latlong.html#cosine-law
अर्जन

4

भू-दूरी-खोज- साथ- MySQL लेख के आधार पर इस कोड की जाँच करें :

उदाहरण: 10 मील के दायरे में मेरे वर्तमान स्थान पर 10 निकटतम होटल खोजें:

#Please notice that (lat,lng) values mustn't be negatives to perform all calculations

set @my_lat=34.6087674878572; 
set @my_lng=58.3783670308302;
set @dist=10; #10 miles radius

SELECT dest.id, dest.lat, dest.lng,  3956 * 2 * ASIN(SQRT(POWER(SIN((@my_lat -abs(dest.lat)) * pi()/180 / 2),2) + COS(@my_lat * pi()/180 ) * COS(abs(dest.lat) *  pi()/180) * POWER(SIN((@my_lng - abs(dest.lng)) *  pi()/180 / 2), 2))
) as distance
FROM hotel as dest
having distance < @dist
ORDER BY distance limit 10;

#Also notice that distance are expressed in terms of radius.

3
simpledb.execSQL("CREATE TABLE IF NOT EXISTS " + tablename + "(id INTEGER PRIMARY KEY   AUTOINCREMENT,lat double,lng double,address varchar)");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2891001','70.780154','craftbox');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2901396','70.7782428','kotecha');");//22.2904718 //70.7783906
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2863155','70.772108','kkv Hall');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.275993','70.778076','nana mava');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2667148','70.7609386','Govani boys hostal');");


    double curentlat=22.2667258;  //22.2677258
    double curentlong=70.76096826;//70.76096826

    double curentlat1=curentlat+0.0010000;
    double curentlat2=curentlat-0.0010000;

    double curentlong1=curentlong+0.0010000;
    double curentlong2=curentlong-0.0010000;

    try{

        Cursor c=simpledb.rawQuery("select * from '"+tablename+"' where (lat BETWEEN '"+curentlat2+"' and '"+curentlat1+"') or (lng BETWEEN         '"+curentlong2+"' and '"+curentlong1+"')",null);

        Log.d("SQL ", c.toString());
        if(c.getCount()>0)
        {
            while (c.moveToNext())
            {
                double d=c.getDouble(1);
                double d1=c.getDouble(2);

            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

2

ऐसा लगता है कि आप दूरी पर कुछ बाध्य के साथ निकटतम पड़ोसी खोज करना चाहते हैं। एसक्यूएल ऐसा कुछ भी समर्थन नहीं करता जहां तक ​​मैं जानता हूं और आपको आर-ट्री या केडी-ट्री जैसे वैकल्पिक डेटा संरचना का उपयोग करने की आवश्यकता होगी ।


2

मेरे लिए निकटतम उपयोगकर्ता खोजें:

मीटर में दूरी

विन्सेंटी के सूत्र में आधारित है

मेरे पास उपयोगकर्ता तालिका है:

+----+-----------------------+---------+--------------+---------------+
| id | email                 | name    | location_lat | location_long |
+----+-----------------------+---------+--------------+---------------+
| 13 | xxxxxx@xxxxxxxxxx.com | Isaac   | 17.2675625   | -97.6802361   |
| 14 | xxxx@xxxxxxx.com.mx   | Monse   | 19.392702    | -99.172596    |
+----+-----------------------+---------+--------------+---------------+

एसक्यूएल:

-- my location:  lat   19.391124   -99.165660
SELECT 
(ATAN(
    SQRT(
        POW(COS(RADIANS(users.location_lat)) * SIN(RADIANS(users.location_long) - RADIANS(-99.165660)), 2) +
        POW(COS(RADIANS(19.391124)) * SIN(RADIANS(users.location_lat)) - 
       SIN(RADIANS(19.391124)) * cos(RADIANS(users.location_lat)) * cos(RADIANS(users.location_long) - RADIANS(-99.165660)), 2)
    )
    ,
    SIN(RADIANS(19.391124)) * 
    SIN(RADIANS(users.location_lat)) + 
    COS(RADIANS(19.391124)) * 
    COS(RADIANS(users.location_lat)) * 
    COS(RADIANS(users.location_long) - RADIANS(-99.165660))
 ) * 6371000) as distance,
users.id
FROM users
ORDER BY distance ASC

पृथ्वी की त्रिज्या: 6371000 (मीटर में)


1

MS SQL संस्करण यहां:

        DECLARE @SLAT AS FLOAT
        DECLARE @SLON AS FLOAT

        SET @SLAT = 38.150785
        SET @SLON = 27.360249

        SELECT TOP 10 [LATITUDE], [LONGITUDE], SQRT(
            POWER(69.1 * ([LATITUDE] - @SLAT), 2) +
            POWER(69.1 * (@SLON - [LONGITUDE]) * COS([LATITUDE] / 57.3), 2)) AS distance
        FROM [TABLE] ORDER BY 3

0

लगता है जैसे आपको सिर्फ PostGIS, SpatialLite, SQLServer2008, या Oracle Spatial का उपयोग करना चाहिए। वे सभी स्थानिक एसक्यूएल के साथ आपके लिए इस प्रश्न का उत्तर दे सकते हैं।


7
आपको लगता है कि आपको यह सुझाव नहीं देना चाहिए कि लोग अपने पूरे डेटाबेस प्लेटफ़ॉर्म को स्विच करते हैं और जब मैं स्पष्ट रूप से "ओरेकल" खोजता हूं, तो मेरी Google खोज में अप्रासंगिक परिणाम दिखाई देते हैं ...
मैंने एक बार एक भालू को कुश्ती दी थी।

0

चरम मामलों में यह दृष्टिकोण विफल हो जाता है, लेकिन प्रदर्शन के लिए, मैंने त्रिकोणमिति को छोड़ दिया है और बस विकर्ण वर्ग की गणना की है।


-13

यह समस्या बहुत कठिन नहीं है, लेकिन अगर आपको इसे अनुकूलित करने की आवश्यकता है तो यह अधिक जटिल हो जाता है।

मेरा क्या मतलब है, क्या आपके डेटाबेस में 100 स्थान हैं या 100 मिलियन हैं? इससे बड़ा फर्क पड़ता है।

यदि स्थानों की संख्या छोटी है, तो उन्हें SQL से और कोड में सिर्फ -> करके निकाल दें

Select * from Location

एक बार जब आप उन्हें कोड में लाते हैं, तो प्रत्येक लेट / लोन और अपने मूल के बीच की दूरी की गणना हैवेर्सिन फार्मूला के साथ करें और इसे सॉर्ट करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.