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.
So for every (x,y) in roadData table find neighbouring data point from
tweetMelbourne and insert those points into another new table.
So I have to do this:
SELECT geo_coordinates_latitude, geo_coordinates_longitude
FROM tweetmelbourne
HAVING ( 3959 * acos( cos( radians(latitude) ) * cos( radians( geo_coordinates_latitude ) ) *
cos( radians( geo_coordinates_longitude ) - radians(longitude) ) + sin( radians(latitude) ) *
sin( radians( geo_coordinates_latitude ) ) ) ) < .1 ORDER BY distance LIMIT 0 , 20;
in which the value of latitude and longitude i have to get from another table :
select longitude,latitude from roadData;
describe tweetmelbourne;
describe roadData;
SELECT geo_coordinates_latitude, geo_coordinates_longitude
FROM tweetmelbourne;
select longitude,latitude from roadData;
The correct syntax of IN() with multiple arguments is : (Val1,Val2) IN(SELECT VAL1,val2..
SELECT t.address,(t.x+t.y) as z
FROM student t
WHERE (t.x,t.y) IN(SELECT x,y FROM tweet)
Also can be done with a join :
SELECT t.address,(t.x+t.y) as z
FROM student t
JOIN tweet s
ON(t.x = s.x and t.y = s.y)
EDIT: I think what you want is:
SELECT s.address,t.x+t.y as z
FROM student s
CROSS JOIN tweet t
Try this:
SELECT s.address, (t.x + t.y) as z
from (SELECT id,x,y FROM `tweet`) as t, student s
WHERE t.id = s.id;
You need to join the two tables, calculating the distance in the ON clause to select the nearby rows.
SELECT *
FROM tweetmelbourne
JOIN roadData
ON ( 3959 * acos( cos( radians(latitude) ) * cos( radians( geo_coordinates_latitude ) ) *
cos( radians( geo_coordinates_longitude ) - radians(longitude) ) + sin( radians(latitude) ) *
sin( radians( geo_coordinates_latitude ) ) ) ) < .1
This will be very slow if the tables are large. It's not possible to use indexes to implement the join, so it will have to perform that complex formula on every pair of rows. You might want to look at MySQL's Spatial Data extensions.
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 have a query like this -
SELECT e.id FROM event e WHERE e.startdatetime<NOW() AND e.isEventDeleted=FALSE AND e.isNeighborlyInvited=TRUE AND e.organized_by!=49 AND e.event_address IN (SELECT id FROM address a WHERE latitude!='' AND longitude!='' AND IFNULL(( 3959 * ACOS( COS( RADIANS(22.6979425) ) * COS( RADIANS( latitude ) ) * COS( RADIANS( longitude ) - RADIANS(75.8597305) ) + SIN( RADIANS(22.6979425) ) * SIN( RADIANS( latitude ) ))),0)<100) AND e.id NOT IN (SELECT eventid FROM event_interest WHERE approvalStatus!='InterestExpressed' AND interested_user=49) AND e.id NOT IN (SELECT eventid FROM event_invite WHERE invited_user=49 )
UNION
SELECT e.id FROM event e WHERE e.isEventDeleted=FALSE AND e.isNeighborlyInvited=TRUE AND e.organized_by!=49 AND EXISTS (SELECT id FROM address a WHERE latitude!='' AND longitude!='' AND e.event_address=id AND IFNULL(( 3959 * ACOS( COS( RADIANS(22.6979425) ) * COS( RADIANS( latitude ) ) * COS( RADIANS( longitude ) - RADIANS(75.8597305) ) + SIN( RADIANS(22.6979425) ) * SIN( RADIANS( latitude ) ))),0)<100) AND NOT EXISTS (SELECT eventid FROM event_interest WHERE e.id =eventid AND approvalStatus!='InterestExpressed' AND interested_user=49) AND NOT EXISTS (SELECT eventid FROM event_invite WHERE eventid=e.id AND invited_user=49 )
ORDER BY e.id,((SELECT AVG(avgr.abc) AS VALUE FROM ( SELECT YEAR(NOW())-YEAR(dob) AS abc FROM user_detail WHERE userid=(SELECT interested_user FROM event_interest WHERE eventid=477 AND approvalStatus='Approve') UNION SELECT YEAR(NOW())-YEAR(dob) AS abc FROM user_detail WHERE userid=(SELECT invited_user FROM event_invite WHERE eventid=477 AND acceptance='Accept')) AS avgr)+(SELECT IFNULL(( 3959 * ACOS( COS( RADIANS(22.6979425) ) * COS( RADIANS( latitude ) ) * COS( RADIANS( longitude ) - RADIANS(75.8597305) ) + SIN( RADIANS(22.6979425) ) * SIN( RADIANS( latitude ) ))),0) FROM address a WHERE latitude!='' AND longitude!='' AND e.event_address=id));
This one is giving me error 1054 unknown column e.id in order clause.
I was checking on google every where its naming mistake, but i am not getting how it is naming mistake please let me know if i am doing any thing wrong.
Try this by removing the e from ORDER BY clause since you are using the UNION statement:
ORDER BY id
instead of
ORDER BY e.id
Your original question has been answered. e.id is no more available after UNION. Only id is.
However there is some things I would like to add:
If I am not mistaken, the only difference between the first statement and the second is that in the first statement you require e.startdatetime to be less than NOW(). So the first statement retrieves a sub set of what the second statement retrieves. So you can remove the first statement completely including the union clause.
You select only from table event. You order first by id. An id should be unique for a table. So the rest of the order by clause is just void; it won't change the order at all.
In a comment to the first answer you got, you remark that you would like to order by a column, but you dont want to show it in your results. To achieve this do the following:
.
select a, b, c
from
(
select a, b, c, d
... -- complete query here
)
order by d;
I have two sql queries which when run independent produces the correct results
Query 1
SELECT id,
(6371 * acos( cos( radians(9.977364864079215) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(76.58620953448485) ) + sin( radians(9.977364864079215) ) * sin( radians( latitude ) ) ) )
AS distance
FROM geodata HAVING distance < 20
ORDER BY distance
LIMIT 0 , 20;
Query 2
SELECT DISTINCT e.* FROM schools e
WHERE (
(e.type = 'preprimary')
)
AND(
e.title LIKE '%government%'
)
LIMIT 0, 10
I want to merge the first query with the second one, so that it should return all "preprimary" type schools with title like "government" located within 20KM radius and the result needs to be ordered by the distance.
How can I merge the two queries? I tried using JOINING the geodata table on the school table. But I dont know the remaining. Sorry, if this is a silly question. I am pretty new to SQL world.
SELECT DISTINCT school.* FROM
( SELECT geodata.id,
(6371 * acos( cos( radians(9.977364864079215) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(76.58620953448485) ) + sin( radians(9.977364864079215) ) * sin( radians( latitude ) ) ) )
AS distance ,school.*
FROM geodata LEFT JOIN school on geodata.id=school.id
WHERE
(school.type = 'preprimary')
AND(
school.title LIKE '%government%'
)
AND school.id IS NOT NULL
HAVING distance < 20 )x
ORDER BY x.distance
LIMIT 0 , 10;
Try this:
SELECT *
From (
SELECT DISTINCT e.* ,
(6371 * acos( cos( radians(9.977364864079215) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(76.58620953448485) ) + sin( radians(9.977364864079215) ) * sin( radians( latitude ) ) )
) as distance
FROM schools e
LEFT JOIN geodata g ON e.id=g.id
WHERE (e.type = 'preprimary')
AND ( e.title LIKE '%government%' )
) as s
Where s.distance < 20
Order by s.distance
It seems that my query is not exactly doing what I want. The query gets a result aslong as the result is 2 or more rows. When I get a single row the query is not getting any result.
In the SELECT I can do DISTINCT (ct.name) but this gives the same problem as the group by.
SELECT
ct.name,
( 3959 * acos(cos(radians(52.779716)) * cos(radians( com.gps_lat )) * cos(radians( com.gps_lon ) -
radians(21.84803)) + sin( radians(52.779716) ) * sin( radians( com.gps_lat )))) as distance
FROM cuisine_types as ct
Left joining company to check if a company is attached to the cuisine_type
LEFT JOIN company AS com ON (com.cuisine_type_id = ct.id)
Here I'm grouping the results so no Cuisine Type appears twice.
this only seems to work when the result is 2 or more rows...
GROUP BY ct.name
Here I'm checking if the distance of the company is within the users preferenced search radius
HAVING distance < 20;
for example if I had 'Fastfood', 'Vegan', and 'Healthy' as Cuisine Types, I only want one of each Cuisine Types no matter how many companies in the search distance are related to that Cuisine Type. So I filter the double Cuisine Types away using the GROUP BY I hope this helps with understanding my approach in this query.
NOTE: There is only one Cuisine Type attached to a company.
Full sql query without comments down here
SELECT ct.name, ( 3959 * acos( cos( radians(52.779716) ) * cos(
radians( com.gps_lat ) ) * cos( radians( com.gps_lon ) -
radians(21.84803) ) + sin( radians(52.779716) ) * sin( radians(
com.gps_lat ) ) ) ) as distance FROM cuisine_types as ct LEFT JOIN
company AS com ON (com.cuisine_type_id = ct.id) GROUP BY ct.name
HAVING distance < 20;
Try this:
SELECT
ct.name,
min( ( 3959 * acos( cos( radians(52.779716) ) * cos( radians( com.gps_lat ) ) * cos( radians( com.gps_lon ) - radians(21.84803) ) + sin( radians(52.779716) ) * sin( radians( com.gps_lat ) ) ) ) ) as distance
FROM
cuisine_types as ct
LEFT JOIN company AS com ON (com.cuisine_type_id = ct.id)
GROUP BY
ct.name
HAVING
distance < 20;
I have these two different queries.
This query pulls the records from "posts" table as per their replies counter. Only posts with replies are returned with this query:
SELECT posts.title, posts.num, posts.status, COUNT( posts_replies.post_num) AS count
FROM posts_replies
INNER JOIN posts ON ( posts_replies.post_num = posts.num )
WHERE posts.status = 1
AND posts.category='uncategorized'
GROUP BY posts.num
And this is a new query that i want to merge with the above one to pull and sort records as per gps.
SELECT num, title, ( 3959 * acos( cos( radians( 37 ) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians( -122 ) ) + sin( radians( 37 ) ) * sin( radians( lat ) ) ) ) AS distance
FROM posts
HAVING distance <75
ORDER BY distance
This query uses the columns lat and long to return records that are within the 75 miles radius of the user.
I am not a sql expert and don't know how to merge both of the queries to gather results having the following criteria:
Only return posts with replies
Sort by their distance
Sort by their number of replies
Any help would be highly appreciated.
Thanks!
The having clause in the second query does not look correct. In most dialects of SQL is would not be allowed without a group by. I forget if MySQL t implicitly treats the whole query as an aggregation (returning one row) or if the having gets converted to a where. In either case, you should be explicit and use where when there are no aggregations.
You can just combine them by putting in the where clause. I would do it with a subquery, to make the variable definitions clearer:
SELECT p.title, p.num, p.status, p.distance,
COUNT( p_replies.post_num) AS count
FROM posts_replies pr INNER JOIN
(select p.*,
( 3959 * acos( cos( radians( 37 ) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians( -122 ) ) + sin( radians( 37 ) ) * sin( radians( lat ) ) ) ) AS distance
from posts p
) p
ON pr.post_num = p.num
WHERE p.status = 1 AND
p.category='uncategorized' and
distance < 75
GROUP BY p.num
order by distance