I found a psql code which looks like this:
select * from (
SELECT *,( 3959 * acos( cos( radians(6.414478) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(12.466646) ) + sin( radians(6.414478) ) * sin( radians( lat ) ) ) ) AS distance
FROM station_location
) al
where distance < 5
ORDER BY distance
LIMIT 20;
find the nearest location by latitude and longitude in postgresql
The problem is I completely don't get it.
Before I used to use mysql and the syntax was completely different:
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;
Find nearest latitude/longitude with an SQL query
How to convert this mysql instruction into psql, so the user's longitude and latitude will be startlng and startlat?
Not commenting on the calculations themselves, this "port" to PostgreSQL should work:
select * from (select SQRT(
POW(69.1 * (10 - 8), 2) +
POW(69.1 * (100 - 10) * COS(10 / 57.3), 2)) AS distance
from table) d where distance < 25 ORDER BY distance;
Related
I am trying to move our site over from using a Lat/Lng field (CHAR), when doing distance. This is how we currently do it:
SELECT ID,( 6371 * acos( cos( radians(52.35462) ) * cos( radians( glinks_Links.Latitude ) ) * cos( radians( glinks_Links.Longitude ) - radians(4.88227) ) + sin( radians(52.35462) ) * sin( radians( glinks_Links.Latitude ) ) ) ) AS distance FROM glinks_Links
WHERE
(
((Latitude BETWEEN (52.35462 - 40/69.0) AND (52.35462 + 40/69.0)) )
AND
(Longitude BETWEEN (4.88227 - 40/42.5) AND (4.88227 + 40/42.5))
)
HAVING distance < 40 ORDER BY distance
...and this comes back as
Showing rows 0 - 24 (1855 total, Query took 0.0288 seconds.)
Then another version that actually gives the "distance" back (as we want to sort by that, and only include the closest);
SELECT ID,st_distance_sphere(POINT(4.88227,52.35462), point_test) / 1000 AS distance FROM glinks_Links WHERE ( ((Latitude BETWEEN (52.35462 - 40/69.0) AND (52.35462 + 40/69.0)) ) AND (Longitude BETWEEN (4.88227 - 40/42.5) AND (4.88227 + 40/42.5)) ) HAVING DISTANCE < 100 ORDER BY distance LIMIT 100
Gives:
Showing rows 0 - 99 (100 total, Query took 0.0237 seconds.)
Then what seems to be the best:
SELECT *
FROM glinks_Links
where st_distance_sphere(POINT(4.88227,52.35462), point_test)/1000 <= 100
Showing rows 0 - 24 (3439 total, Query took 0.0015 seconds.)
The issue with that though - is that it doesn't provide me with the distance! What I want to do is query and grab the 100 closest. Is there a way I can do this, without compramising on the speed?
be sure you have proper composite index on
create index my_idx ON glinks_Links (Latitude, Longitude, ID)
And you don't need unuseful () for where condition (using AND)
SELECT ID,( 6371 * acos( cos( radians(52.35462) ) * cos( radians( glinks_Links.Latitude ) )
* cos( radians( glinks_Links.Longitude ) - radians(4.88227) ) + sin( radians(52.35462) )
* sin( radians( glinks_Links.Latitude ) ) ) ) AS distance
FROM glinks_Links
WHERE Latitude BETWEEN (52.35462 - 40/69.0) AND (52.35462 + 40/69.0)
AND Longitude BETWEEN (4.88227 - 40/42.5) AND (4.88227 + 40/42.5)
HAVING distance < 40
ORDER BY distance
for the second version
SELECT ID, st_distance_sphere(POINT(4.88227,52.35462), point_test) / 1000 AS distance
FROM glinks_Links
WHERE Latitude BETWEEN (52.35462 - 40/69.0) AND (52.35462 + 40/69.0)
AND Longitude BETWEEN (4.88227 - 40/42.5) AND (4.88227 + 40/42.5)
HAVING DISTANCE < 100
ORDER BY distance
LIMIT 100
you should use a composite index on
create index myidx ON glinks_Links (Latitude, Longitude, point_test, ID )
I have a table in mysql call BRANCH
===============================
Branch_id latitude longitude
===============================
1 3.109421 101.622913
2 3.101121 101.644913
How can i select kilometer calculation from this table when I pass in my current location latitude / longitude?
Example:
If I pass in my current location = 3.122221 101.343913
============================================
Branch_id latitude longitude distance(km)
============================================
1 3.109421 101.622913 0.4
2 3.101121 101.644913 0.6
Edited (Solved):
SELECT p.title,p.subtitle,p.desc,p.image,p.promotion_id,p.merchant_id,p.date_from,p.date_to,m.merchant_name,p.view,mb.latitude,mb.longitude,
(6371 * acos (cos( radians(3.158704)) * cos( radians(mb.latitude))
* cos( radians(mb.longitude) - radians(101.713963)) + sin(radians(3.158704))
* sin( radians(mb.latitude)))) AS distance
FROM merchant_branch as mb
left join merchant m on mb.merchant_id = m.merchant_id
left join promotion p on p.merchant_id = m.merchant_id
where p.promotion_id is not null order by distance asc
From: https://developers.google.com/maps/solutions/store-locator/clothing-store-locator
Here's the SQL statement that finds the closest 20 locations within a
radius of 25 miles to the -33, 151 coordinate. It calculates the
distance based on the latitude/longitude of that row and the target
latitude/longitude, and then asks for only rows where the distance
value is less than 25, orders the whole query by distance, and limits
it to 20 results. To search by kilometers instead of miles, replace
3959 with 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 < 25 ORDER BY distance LIMIT 0 , 20;
I used the following sql for mySQL but I now need to use this for a Firebird database. I have searched and read the Firebird documentation but can't seem to locate an alternative. In Firebird 'radians' and 'limit' both are not supported. Has anyone successfully done similar in Firebird?
SELECT zip, ( 3959 * acos( cos( radians(38.6285426) ) * cos( radians( lat ) )
* cos( radians( lng ) - radians(-86.05296039999999) ) + sin( radians(38.6285426) ) * sin(radians(lat)) ) ) AS distance
FROM zipcodes
HAVING distance < 25
ORDER BY distance
LIMIT 0 , 20;
The radians function in mySQL "returns the argument X, converted from degrees to radians". You don't need builtin function to do that, it's rather simple math: radians = degrees × π / 180º. You could create an convenience view with calculated columns for deg-to-rad conversion, to make the query easier to read. BTW, Firebird has builtin function for retrieving π value.
Instead of LIMIT Firebird supports ROWS syntax:
SELECT <columns> FROM ...
[WHERE ...]
[ORDER BY ...]
ROWS <m> [TO <n>]
For anyone having a similar issue, here was my solution for Firebird that returns all zips codes within a certain mile radius of a Lat/long (Great Circle) in one query.
select zipcode from(
SELECT zipcode, ( 3959 * acos( cos( 38.6285426/57.2958 ) * cos( lat/57.2958 )
* cos( lon/57.2958 - -86.05296039999999/57.2958 ) + sin( 38.6285426/57.2958 ) * sin(lat/57.2958) ) ) AS distance
FROM zip_codes)
where distance < 20
ORDER BY distance
i want to search near by location with given latitude and longitude in mysql
latitude is : 26.902
longitude is : 75.793
and distance is : 30
Query is :
SELECT
id, (
3959 * acos (
cos ( radians(26.902) )
* cos( radians( latitude ) )
* cos( radians( longitude ) - radians(75.793) )
+ sin ( radians(26.902) )
* sin( radians( latitude ) )
)
) AS distance
FROM business
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;
Result:
i am getting a record with distance is 3.58,
record lat/long are 26.89 / 75.74
but when i check online on other site i got distance 5.759 miles .
Some code available here as a Stored Function: http://mysql.rjweb.org/doc.php/latlng .
I have a MySQL database with the following table
int - id
float 2,6 - long
float 2,6 - lat
int - radius
I want to create a SQL query which returns the ID & Distance from a given location(long & lat)
I found the following piece of code which works:
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 < 25 ORDER BY distance LIMIT 0 , 20;
I want to alter this query to return only the rows where the computed length is smaller the radius (a column i my table)
replacing the 25 with the radius doesn't work.
Is there a way to achieve that without using two SQL queries ?
problem is occured because the result distance is in float and radius is an integer datatype so you need to CAST radius as float. try below
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 < CAST (radius AS float) ORDER BY distance LIMIT 0 , 20;
HAPPY TO HELP :)