MySQL sub query with two columns - how to hide the second column? - mysql

I'm having a difficult time wrapping my head around how to do this, even with all the searching and reading I've done on this!
I have a query I am using to try to pull all users from a database that have a zip code that falls within a certain distance of a given decimal coordinate. Here's the query that I am running:
select distinct watch_list.username, enabled
from watch_list, registered_users
where watch_list.username = registered_users.username AND watch_list.watchzip = (
SELECT zip,
( 3959 * acos( cos( radians('29.7632800') ) *
cos( radians( lat ) ) *
cos( radians( lng ) -
radians('-95.3632700') ) +
sin( radians('29.7632800') ) *
sin( radians( lat ) ) ) )
AS distance from zip
HAVING distance <= '10');
There error I get back is expected, as my sub query is returning two columns:
MySQL said: Documentation
#1241 - Operand should contain 1 column(s)
How can I do this and filter on the distance without the sub query returning both columns?
P.S. Just for completion and information sake, the "zip" table contains a list of all zip codes in the U.S. along with their decimal coordinates.

Just move the operation out of the column list:
select distinct watch_list.username, enabled
from watch_list, registered_users
where watch_list.username = registered_users.username
AND watch_list.watchzip = (
SELECT zip
from zip
WHERE ( 3959 * acos( cos( radians('29.7632800') ) *
cos( radians( lat ) ) *
cos( radians( lng ) -
radians('-95.3632700') ) +
sin( radians('29.7632800') ) *
sin( radians( lat ) ) ) ) <= '10');
Edit: As P.Salmon mentions, you probably also want to change AND watch_list.watchzip = to AND watch_list.watchzip IN.

Related

Longitude latitude query but only rows that match column in same table

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.

Why won't this query return results that are 0?

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.

Combining multiple where conditions in mysql SELECT query

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;

Using Match in mysql longitude and latitude search

I'm trying to put together a simple location search where people can enter a keyword and a location and the nearest results are displayed.
I can get the mysql statement for the free text search and the radius search working individually but not together...
My attempt is below...
SELECT
place_id,
(
3959 * acos (
cos ( radians(52.586973) )
* cos( radians( lat ) )
* cos( radians( lng ) - radians(-2.128820000000019) )
+ sin ( radians(52.586973) )
* sin( radians( lat ) )
)
) AS distance
FROM places
HAVING distance < 30,
MATCH (title,details) AGAINST ('Cafe') AS score
FROM places
WHERE MATCH (title, details)
AGAINST ('Cafe')
ORDER BY distance

Count query returning unexpected results

I have this query:
SELECT
count(*) as count ,
( 3959 * acos(
cos( radians( 37.774929 ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians( -122.419418 ) )
+ sin( radians( 37.774929 ) ) * sin( radians( lat ) )
) ) AS distance
FROM users
HAVING distance < 150
I thought it was going to give me the count of users who are in the radius of 150 miles. But instead it gave me a total number of users. And if lat/lng were different, it would give me zero number of users when there were some users there.
Any ideas how to change this query in order to get the number of users within the 150mi radius?
Thanks!
You want to use a WHERE clause
select count(*) as count from users WHERE ( 3959 * acos( cos( radians( 37.774929 ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians( -122.419418 ) ) + sin( radians( 37.774929 ) ) * sin( radians( lat ) ) ) ) < 150
To expand on Dirk's answer...
The WHERE clause is applied to the records after they've all be joined up.
The HAVING clause is applied after any aggregation is complete.
Also, as in Dirk's answer, you don't need to have the calculation in the SELECT to be able to use it elsewhere.
So, Dirk's answer calculates the Distance for each individual ROW (after joins, before aggregation), then discards any with a distance of 150 or more. It only THEN aggregates and counts everything up.