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 :)
Related
After a lot of reading I have written these 3 sql statement and I want to automate and combine these 3 sql statement.
select longitude,latitude from roadData;
SELECT geo_coordinates_latitude, geo_coordinates_longitude,
( 3959 * acos( cos( radians('-37.964637158') ) * cos( radians( geo_coordinates_latitude ) ) *
cos( radians( geo_coordinates_longitude ) - radians('144.408476215') ) + sin( radians('-37.964637158') ) *
sin( radians( geo_coordinates_latitude ) ) ) ) AS distance
FROM tweetmelbourne HAVING distance < .1 ORDER BY distance LIMIT 0 , 20;
Insert into roadTweets(longitude,latitude) values(144.408476215,-37.964637158);
**
What basically i want to do is pick all the coordinates from roadData
one by one and then find all the point in tweetMelbourne within 20
miles of it and insert those point into another table.
**
describe tweetmelbourne;
describe roadData;
I'm not enterily sure on this, so please let me know if this works:
Insert into roadTweets(longitude,latitude) values(SELECT geo_coordinates_latitude, geo_coordinates_longitude,
( 3959 * acos( cos( radians(SELECT latitude FROM roadData) ) * cos( radians( geo_coordinates_latitude ) ) *
cos( radians( geo_coordinates_longitude ) - radians(SELECT longitude FROM roadData) ) + sin( radians(latitude) ) *
sin( radians( geo_coordinates_latitude ) ) ) ) AS distance
FROM tweetmelbourne HAVING distance < .1 ORDER BY distance LIMIT 0 , 20);
I guess this should be:
select * from tweetmelbourne t, roadData r
where distance(r.longitude,r.latitude,t.geo_coordinates_longitude,t.geo_coordinates_latitude) < 20;
And either implement distance funcion or replace distance(r.longitude,r.latitude,t.geo_coordinates_longitude,t.geo_coordinates_latitude) with formula calculating distance so. In oracle you can use package SDO_GEOMETRY.
I've looked and looked and tried and tried with no success. I have a query that I use to display users within a certain distance range. It works great, but it returns all users from my users table, and I want it to only return users where the value in account_type is equal to '1'. So basically different kinds of account types share my users table and on this page I only want one type of user to be display. I've tried all sorts of things, including joining the same table which I know makes no sense and it didn't work anyway. Basically, I would like to know where in this query I can add a 'WHERE' clause to check the column named 'account_type'.
Here's my functional query:
SELECT `user_id`, ( 3959 * acos( cos( radians('".$lat."') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('".$lng."') ) + sin( radians('".$lat."') ) * sin( radians( lat ) ) ) ) AS distance FROM users HAVING distance <= '".$dist."' ORDER BY distance
Since I only want to return users from that table that have account_type = 1, I tried doing many different variations of the following, with no success:
SELECT `user_id`, `account_type`, ( 3959 * acos( cos( radians('".$lat."') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('".$lng."') ) + sin( radians('".$lat."') ) * sin( radians( lat ) ) ) ) AS distance FROM users ***WHERE `account_type` = '1'*** HAVING distance <= '".$dist."' ORDER BY distance
SELECT `user_id`, `account_type`, ( 3959 * acos( cos( radians('".$lat."') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('".$lng."') ) + sin( radians('".$lat."') ) * sin( radians( lat ) ) ) ) AS distance FROM users HAVING distance <= '".$dist."' ***WHERE `account_type` = '1'*** ORDER BY distance
any many others though I won't pollute this topic any further. Can someone please tell me what I'm doing wrong? Thank you
#rhavendc was correct. I'm a moron. The account that I created to test this I used some far away location and though there are more than 20 test accounts on my site, there were none within 100miles of the crazy location my test account was using as far as those matching account_type='1'
So once I realized that it took 2 seconds to just use this query to get the proper result
$qry="SELECT user_id, ( 3959 * acos( cos( radians('".$lat."') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('".$lng."') ) + sin( radians('".$lat."') ) * sin( radians( lat ) ) ) ) AS distance FROM users WHERE account_type = '1' HAVING distance <= '".$dist."' ORDER BY distance";
Thanks for everyone's input. I apologize for my stupidity.
Using haversine, the following query finds all rows that have coordinates within a 10 mile radius of the inputted coordinates.
SELECT *
, ( 3959 * acos( cos( radians($locationLatitude) )
* cos( radians( endingLatitude ) )
* cos( radians( endingLongitude ) - radians( $locationLongitude ) )
+ sin( radians( $locationLatitude) )
* sin( radians( endingLatitude ) ) ) ) AS distance
FROM trips
HAVING distance < 10
ORDER
BY distance
LIMIT 0 , 10;
However, it does not return rows that have the same exact coordinates as the coordinates inputted. Why is this?
You're using incorrect syntax: Change HAVING to WHERE and use a subquery so you can refer to the alias of the calculation rather than having to repeat the formula:
select * from (
select *, ( 3959 * acos( cos( radians($locationLatitude) )
* cos( radians( endingLatitude ) )
* cos( radians( endingLongitude ) - radians( $locationLongitude ) )
+ sin( radians( $locationLatitude) )
* sin( radians( endingLatitude ) ) ) ) AS distance
from trips) x
WHERE distance < 10
ORDER BY distance
LIMIT 0, 10
HAVING is for conditions on aggregated values for groups, eg GROUP BY FOO HAVING COUNT(*) > 3, but you aren't doing any grouping; you need a simple where clause.
Unfortunately, mysql has "lenient" grouping syntax which has allowed your statement to execute without a syntax error, even though it is logically unsound. The same query run on other databases would cause an error.
I am attempting to return only rows where the latitude and longitude being passed into the query, when compared to the latitude and longitude stored in the database, is a certain amount of miles apart.
The query is as follows:
SELECT
c.google_theatre_id
AS cinema_id,
c.name
AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) ) )
AS distance
FROM
google_cinemas c, app_users u
WHERE
distance < u.range
AND
u.id = 126
ORDER BY
distance
The query is designed to get the distance and then compare it to a column (range) in the app_users table.
When running the query, I'm getting an error of distance being an unknown column.
As this is a virtual column, is there a different way of comparing?
Thanks :)
you need to use HAVING instead of WHERE.. think of it this way WHERE is when you make an order at a restraunt and HAVING is picking stuff off of the plate when it comes to your table... you cannot reference an alias before the plate comes to your table only after it has been built
SELECT
c.google_theatre_id AS cinema_id,
c.name AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) )
) AS distance
FROM google_cinemas c, app_users u
WHERE u.id = 126
HAVING distance < u.range
ORDER BY distance
alternatively you can use it as a sub query which could be faster since HAVING re-evaluates the entire query.
SELECT *
FROM
( SELECT
c.google_theatre_id AS cinema_id,
c.name AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) )
) AS distance,
u.range
FROM google_cinemas c, app_users u
WHERE u.id = 126
ORDER BY distance
)t
WHERE distance < range
So here's my issue:
I have a database table where I have latitudes and longitudes and a timestamp. I need to be able to search through this table using PHP. What would the query be to find rows with lats and lons in a certain range, and, on top of this, in a certain time frame.
I have found two separate queries that would work while browsing through the internet, but I can't find a clear way to combine multiple conditions.
The two queries are:
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;
enter code here
SELECT * FROM `table` WHERE `date_field` BETWEEN 'date1' AND 'date2'
I need to find top twenty results where timestamp and lat and long are in range.
Thanks!
EDIT: All fields are in the same table.
If all data is in the same table, you can do:
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
WHERE date_field BETWEEN 'date1' AND 'date2'
HAVING distance < 25
ORDER BY distance
LIMIT 0 , 20;