I have a table that contains column called func_id , latitude and longitude. Im trying to get the min distance row and return the func_id by a function.
I tried:
function Get_Min_func_id($lat, $long){
$query = mysql_query("
select func_id,
MIN( 3959 * acos( cos( radians('$lat') )
* cos( radians( latitude ) )
* cos( radians( longitude ) - radians('$long') )
+ sin( radians('$lat') )
* sin( radians( latitude ) ) ) ) AS distance
from entregas
");
return #mysql_result($query, 0, 'func_id');
}
But its not working fine. It is returning only the same func_id.
This is the query that you want:
select func_id,
( 3959 * acos( cos( radians('$lat') )
* cos( radians( latitude ) )
* cos( radians( longitude ) - radians('$long') )
+ sin( radians('$lat') )
* sin( radians( latitude ) ) ) ) AS distance
from entregas
order by distance asc
limit 1;
Your query will return the minimum distance, but an arbitrary value for func_id. As a general rule, you should always have the same columns in a group by as in the select, unless you are using aggregation functions. In this case, you have an aggregation query with no group by, so there should be no additional columns.
Related
I am trying to run a query that finds the places near my location, but every time I try to run it, it returns the following error:
column "distance" does not exist
If I remove distance and only leave up to the FROM posts, it returns the post id and the distance column.
But if I leave it in the original way, it returns the error.
SELECT id,
( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) *
sin( radians( latitude ) ) ) ) AS distance
FROM posts
HAVING distance < 25
ORDER BY distance;
You can't use a column alias in other places in the same query. You'll have to either repeat the entire expression in your HAVING and ORDER BY or use your existing query as a sub-query and apply the HAVING and ORDER BY to the outer query, or use a CTE if your RDBMS supports it.
SELECT id, distance FROM
(SELECT id, ( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) *
sin( radians( latitude ) ) ) ) AS distance FROM posts) p
WHERE distance < 25 ORDER BY distance;
you need to put CTA to order it by distance
I want to apply the radius on nearest location. SQL query is working before HAVING clause. If I execute whole query then its giving error is :
"Invalid column name 'dist'."
My Sql query is:
SELECT name, latitude, longitude, ( 3959 * acos( cos( radians(30.901) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(75.8573) ) + sin( radians(30.901) ) *
sin( radians( latitude ) ) ) ) AS dist
FROM res HAVING dist <= 25 ORDER BY dist ASC
I tried same above query. But that is half working. If I execute without HAVING clause then its working. Otherwise giving me an error:
"Invalid column name 'dist'".
having is for groupped data. use where instead.
use this :
SELECT *
FROM (
SELECT name, latitude, longitude, ( 3959 * acos( cos( radians(30.901) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(75.8573) ) + sin( radians(30.901) ) *
sin( radians( latitude ) ) ) ) AS dist
FROM res
) myResult
WHERE myResult.dist <= 25
ORDER BY myResult.dist ASC
Use a subquery to define the columns, then select from that.
See if this works for you.
Select name, latitude, longitude, dist
From (
SELECT name, latitude, longitude, ( 3959 * acos( cos( radians(30.901) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(75.8573) ) + sin( radians(30.901) ) *
sin( radians( latitude ) ) ) ) AS dist
FROM res ) A
WHERE dist <= 25 ORDER BY dist ASC
I'm trying to get the total average price within a radius by given latitude and longitude.
I've tried something like this:
SELECT avg(price) AS average,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental`
HAVING distance <= 20
But the result is empty.
The result should looks like this:
average = 185
Thanks for your help.
You are using the HAVING in a way that MySQL extends it. But because you have AVG(), it places its normal role as well.
You are going to need a subquery or to move the distance measurement to the WHERE clause:
SELECT avg(price) as average
FROM (SELECT r.*,
( 6371 * acos( cos( radians(37.3541079) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-121.9552356) ) + sin( radians(37.3541079) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM `Rental` r
) r
WHERE distance <= 20;
In other words, calculate the distance. Then use WHERE to filter the rows. And then aggregate for the price.
I am trying to get drivers who visited certain area from SQL server 2014 database. The table is named DriverLocationHistory.
Here is the sql query I used :
SELECT id, ( 6371 * acos( cos( radians(37) ) * cos( radians( latitude ) )
* cos( radians( Longitude ) - radians(-122) ) + sin( radians(37) ) * sin(radians(latitude)) ) ) AS distance
FROM DriverLocationHistory
HAVING distance < 5
ORDER BY distance
When I execute the query I get this error :
Msg 207, Level 16, State 1, Line 7
Invalid column name 'distance'.
I was asked to provide a way to do this with the built-in geography data type. That's a bit too long for a comment, so here goes:
ALTER TABLE [DriverLocationHistory] ADD geoLocation
AS geography::Point([Latitude], [Longitude], 4236);
declare #p geography = geography::Point(37, -122, 4236);
select * from [DriverLocationHistory]
where geoLocation.STDistance(#p) < 5000;
A spatial index should help with the SARGability of the where clause in the select.
You can't use an alias in a Where clause. This is because the where clause is processed before, or as, the result set is being generated, and the alias is not assigned until the result set has been generated. Only in an aggregate query (where there is a group By) can you do this, because then the alias is assigned to the value of some expression before the aggregation is processed. Your query must use the full expression in both the where clause (does not need to be a Having clause) and in the order by:
SELECT id,
( 6371 * acos( cos( radians(37) )
* cos( radians( latitude ) )
* cos( radians( Longitude ) - radians(-122) ) + sin( radians(37) )
* sin(radians(latitude)) ) ) AS distance
FROM DriverLocationHistory
Where 6371 * acos( cos( radians(37) )
* cos( radians( latitude ) )
* cos( radians( Longitude ) - radians(-122) ) + sin( radians(37) )
* sin(radians(latitude)) ) < 5
ORDER BY 6371 * acos( cos( radians(37) )
* cos( radians( latitude ) )
* cos( radians( Longitude ) - radians(-122) ) + sin( radians(37) )
* sin(radians(latitude)) )
as mentioned in comments, you can use the alias in the order by,
Or, you could also perform the computation and alias assignment in a subquery:
SELECT id, distance
From (Select ( 6371 * acos( cos( radians(37) )
* cos( radians( latitude ) )
* cos( radians( Longitude ) - radians(-122) ) +
sin( radians(37) )
* sin(radians(latitude)) ) ) distance
From DriverLocationHistory)z
Where distance < 5
ORDER BY distance
Here is my table named "test" -
Check the snapshot here test
And then my row items: here - rowitems
I'm using the haversine formula, he is my query
SELECT *, ( 3960 * acos( cos( radians( 33.650800 ) ) *
cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians( -117.891729 ) ) +
sin( radians( 33.650800 ) ) * sin( radians( Latitude ) ) ) ) AS Distance
FROM test
For some reason the HAVING or WHERE clause is not working with Distance.
It works with Latitude or Longitude.
But when I try to do WHERE Distance < 10 or HAVING Distance < 10. It says Distance is an invalid column name.
I need to be able to do this, and make a query using Distance. Any help would be appreciated.
You cannot use calculated fields on a where or having clause. Create a view or use a subquery
Try this:
select * FROM (SELECT *, ( 3960 * acos( cos( radians( 33.650800 ) ) *
cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians( -117.891729 ) ) +
sin( radians( 33.650800 ) ) * sin( radians( Latitude ) ) ) ) AS Distance
FROM test) as T WHERE T.Distance < 10
You need to put your query into a subquery, or a view, or a CTE (common table expression).
Here is an example for your task with a CTE:
WITH cte_test (Name, Latitude, Longitude, Distance)
AS
(
SELECT Name, Latitude, Longitude,
3960 * acos(cos(radians(33.650800))
* cos(radians( Latitude ) )
* cos( radians( Longitude ) - radians( -117.891729 ) )
+ sin( radians( 33.650800 ) ) * sin( radians( Latitude ) ) ) )
AS Distance
FROM test
)
SELECT * from cte_test where Distance < 10 ;
A CTE is a kind of "temporary view". It is also a powerful instrument which can also be used for creating recursive queries.