SELECT GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ",")
, SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",1) latitude
, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",2),",",-1) longitude
, ( 6371 * acos( cos( radians(52.2734487789) ) * cos( radians(latitude ) ) * cos( radians(longitude ) - radians(10.5438383386) ) + sin( radians(52.2734487789) ) * sin( radians(latitude ) ) ) ) AS distance
FROM `wp_umkreissuche_posts` AS posts
, `wp_umkreissuche_postmeta` AS postmeta
WHERE posts.post_type = "adresses"
AND posts.ID=postmeta.post_id
AND postmeta.meta_key="latitude"
OR posts.post_type="adresses"
AND posts.ID=postmeta.post_id
AND postmeta.meta_key="longitude"
GROUP
BY postmeta.post_id
HAVING distance < 0.5
ORDER
BY postmeta.post_id
, distance ASC
This is your query, formatted a bit better and with clearer join syntax:
SELECT GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),
SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",1) AS latitude,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",2),",",-1) AS longitude,
( 6371 * acos( cos( radians(52.2734487789) ) * cos( radians(latitude ) ) * cos( radians(longitude ) - radians(10.5438383386) ) + sin( radians(52.2734487789) ) * sin( radians(latitude ) ) ) ) AS distance
FROM `wp_umkreissuche_posts` AS posts JOIN
`wp_umkreissuche_postmeta` AS postmeta
ON posts.ID = postmeta.post_id AND posts.post_type = 'adresses' AND
(postmeta.meta_key IN ('latitude', 'longitude')
)
GROUP BY postmeta.post_id
HAVING distance < 0.5
ORDER BY postmeta.post_id, distance ASC
Your direct problem is that latitude and longitude are defined in the select, so they cannot be used at the same select level. The normal solution is to repeat the expression or to use a subquery, so the alias is known. However, the logic for your query doesn't look write. I suspect it should be something more like this:
SELECT CONCATE_WS, ',', lat.postmeta.meta_value, lng.postmeta.meta_value) ,
lat.postmeta.meta_value AS latitude,
lng.meta_value AS longitude,
. . .
FROM `wp_umkreissuche_posts` posts JOIN
`wp_umkreissuche_postmeta` lat
ON posts.ID = postmeta.post_id AND posts.post_type = 'adresses' AND lat.meta_key = 'latitude' JOIN
`wp_umkreissuche_postmeta` lng
ON posts.ID = postmeta.post_id AND posts.post_type = 'adresses' AND lng.meta_key = 'longitude'
HAVING distance < 0.5
ORDER BY postmeta.post_id, distance ASC;
Note: you can use the having without a group by in MySQL. It then behaves like a where but it allows column aliases.
You cannot use an alias name in another field in the same query unless you use a subquery or join.
Use
(SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",1)
instead of latitude.
Try this way:
SELECT GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),
SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",1) AS latitude,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",2),",",-1) AS longitude,
( 6371 * acos( cos( radians(52.2734487789) ) * cos( radians(latitude ) ) * cos( radians(longitude ) - radians(10.5438383386) ) + sin( radians(52.2734487789) ) * sin( radians((SUBSTRING_INDEX(GROUP_CONCAT(TRIM(postmeta.meta_value) SEPARATOR ","),",",1)) ) ) ) AS distance
FROM wp_umkreissuche_posts AS posts, wp_umkreissuche_postmeta AS postmeta
WHERE posts.post_type="adresses" AND posts.ID=postmeta.post_id AND postmeta.meta_key="latitude" OR posts.post_type="adresses" AND posts.ID=postmeta.post_id AND postmeta.meta_key="longitude"
GROUP BY postmeta.post_id HAVING distance < 0.5
ORDER BY postmeta.post_id, distance ASC
Related
I am trying multiple having but problem is with multiple having conditions any one guide me how to adjust two having in same query
Here is SQL Query :
SELECT schools.*,
schools.required_gpa AS gpa,
(college_act_scores.min_act + college_act_scores.max_act)/2 AS act_avrg ,
(college_sat_scores.min_sat + college_sat_scores.max_sat)/2 AS sat_avrg,
(6371 * Acos( Cos( Radians(31.4699398) ) * Cos( Radians( latitude ) ) * Cos( Radians( longtitude ) - Radians(74.3096108) ) + Sin( Radians(31.4699398) ) * Sin( Radians( latitude ) ) ) ) AS distance
FROM schools
LEFT JOIN college_paying1
ON college_paying1.college_id = schools.id
LEFT JOIN college_act_scores
ON (
college_act_scores.college_id = schools.id
AND college_act_scores.college_child_sub_cat_id = 144)
LEFT JOIN college_sat_scores
ON (
college_sat_scores.college_id = schools.id
AND college_sat_scores.college_child_sub_cat_id = 136)
WHERE college_paying1.on_campus >= 0
AND college_paying1.on_campus <=80348
AND college_paying1.college_child_sub_cat_id =120
HAVING (
act_avrg BETWEEN 0 AND 36)
having (
sat_avrg BETWEEN 0 AND 1600)
GROUP BY schools.id
ORDER BY distance ASC limit 0, 10
You need to move the HAVING clause after GROUP BY. Document here
This should work:
select schools.*,schools.required_gpa as gpa,
(college_act_scores.min_act + college_act_scores.max_act)/2 as act_avrg ,
(college_sat_scores.min_sat + college_sat_scores.max_sat)/2 as sat_avrg,
(6371 * acos( cos( radians(31.4699398) ) * cos( radians( latitude ) ) * cos( radians( longtitude ) - radians(74.3096108) ) + sin( radians(31.4699398) ) * sin( radians( latitude ) ) ) ) AS distance
from schools
left join college_paying1 on college_paying1.college_id = schools.id
left join college_act_scores on (college_act_scores.college_id = schools.id
AND college_act_scores.college_child_sub_cat_id = 144)
left join college_sat_scores on (college_sat_scores.college_id = schools.id
AND college_sat_scores.college_child_sub_cat_id = 136)
where college_paying1.on_campus >= 0
and college_paying1.on_campus <=80348
and college_paying1.college_child_sub_Cat_id =120
GROUP BY schools.id
HAVING ( act_avrg BETWEEN 0 AND 36) AND ( sat_avrg BETWEEN 0 AND 1600)
order by distance asc
LIMIT 0 , 10
Hope this helps! Cheers!
Instead of
HAVING ( act_avrg BETWEEN 0 AND 36) HAVING ( sat_avrg BETWEEN 0 AND 1600)
Put
HAVING (act_avrg BETWEEN 0 AND 36) AND (sat_avrg BETWEEN 0 AND 1600)
So I have this query:
SELECT P.*,
( 3959 * acos( cos( radians('37.785834') )
* cos( radians( CA.lat ) )
* cos( radians( CA.lng )
- radians('-122.406417') )
+ sin( radians('37.785834') )
* sin( radians( CA.lat ) ) ) ) AS distance
FROM adp2_posts as P
JOIN adp2_offer_details C ON C.merchant_id = P.ID
JOIN adp2_addresses CA ON CA.address_id = C.address_id
WHERE P.post_type = 'merchant'
AND P.post_status = 'publish'
AND CA.mm = "dallasftworth"
AND C.cats RLIKE CONCAT("[[:<:]]", REPLACE(199, ",", "[[:>:]]|[[:<:]]"), "[[:>:]]")
GROUP BY CA.address_id, P.ID
HAVING (distance < 999999999999999999 AND P.coupon_count > 0) ORDER BY distance ASC LIMIT 0 , 20
I expect it to return unique values from LEFT table, but it returns duplicates too.
Results:
I am a bit confused by this one.
Sorry for not providing the full context, its been a long day, but i finally figured it out.
Here's the end query:
SELECT P.*, MIN(( 3959 * acos( cos( radians('37.785834') ) * cos( radians( CA.lat ) ) * cos( radians( CA.lng ) - radians('-122.406417') ) + sin( radians('37.785834') ) * sin( radians( CA.lat ) ) ) )) AS distance FROM adp2_posts as P JOIN adp2_offer_details C ON C.merchant_id = P.ID JOIN adp2_addresses CA ON CA.address_id = C.address_id WHERE P.post_type = 'merchant' AND P.post_status = 'publish' AND CA.mm = "dallasftworth" AND C.cats RLIKE CONCAT("[[:<:]]", REPLACE(199, ",", "[[:>:]]|[[:<:]]"), "[[:>:]]") GROUP BY P.ID HAVING (distance < 999999999999999999 AND P.coupon_count > 0) ORDER BY distance ASC LIMIT 0 , 20
The problem was that, CA.address_id where different and GROUP BY took it as unique values. What i did, is just select P.* with smallest distance(this is exactly what my business logic asks for).
I have following mysql query:
SELECT a.id
, ( 3959 * acos( cos( radians(a.latitude) ) * cos( radians( w.latitude ) )
* cos( radians( w.longitude ) - radians(-a.longitude) )
+ sin( radians(a.latitude) ) * sin(radians(w.latitude)) ) ) distance
FROM global_restaurants a
JOIN webgeocities w
ON w.name = a.locality
AND w.country_code = a.country
AND a.latitude LIKE w.latitude
JOIN states s
ON s.state_code = w.state_code
AND w.country_code = s.country_code
WHERE a.city_id = 0
After execution it returns:
id distance
70 6665.478678743614
70 6496.46971480875
70 6725.900646648246
70 6733.5156930808
90 6969.449661399672
90 7252.889875588891
I want it to only return 2 rows with minimum distance like:
id distance
70 6496.46971480875
90 6969.449661399672
add order by at the end of your query:
order by distance ASC LIMIT 2;
now you calculating the distance but
at end of the query you must sort them and limit the returns row count..
.
NOTE:
i think you have a small mistake on your query
the 3959 is for miles but i think the values are in meter
your full query can be like this:
select a.id, ( 6371000 * acos( cos( radians(a.latitude) ) * cos( radians( w.latitude ) )
* cos( radians( w.longitude ) - radians(-a.longitude) ) + sin( radians(a.latitude) ) * sin(radians(w.latitude)) ) ) AS distance
from `global_restaurants` as a INNER JOIN webgeocities as w ON (w.name = a.locality AND w.country_code = a.country and a.latitude like w.latitude) INNER JOIN
states AS s ON (s.state_code = w.state_code and w.country_code = s.country_code) where a.city_id = '0' ORDER BY distance ASC LIMIT 2;
For simplicity, let's assumed that you have your query in view - stack, then your query should look like this
select stack.* from stack join (
SELECT id, GROUP_CONCAT(distance ORDER BY
distance asc) grouped_distance FROM stack GROUP BY id
) group_distance on group_distance.id=stack.id
where find_in_set(stack.distance,group_distance.grouped_distance)between 1 and 2;
i have two sql queries those are following
1) SELECT a.* FROM modzzz_listing_main as a LEFT JOIN modzzz_listing_rating as b ON a.id=b.gal_id WHERE LTRIM(a.city) = 'Houston' AND a.state = 'TX' AND a.tags LIKE '%Barber Shop%' ORDER BY b.gal_rating_sum DESC LIMIT 0 ,10
2) SELECT zip_code ,( 3959 * acos( cos( radians('41.97734070') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('-70.97234344') ) + sin( radians('41.97734070') ) * sin( radians( latitude ) ) ) ) AS distance FROM city_finder WHERE latitude IS NOT NULL AND longitude IS NOT NULL HAVING distance < 20 ORDER BY distance ASC
how can i combine this two queries by the condition `
modzzz_listing_main.zip=city_finder.zip_code
` .i am totally confused..please any one help me..
to see the join easier:
select * from
(
SELECT a.* FROM modzzz_listing_main as a LEFT JOIN modzzz_listing_rating as b ON a.id=b.gal_id WHERE LTRIM(a.city) = 'Houston' AND a.state = 'TX' AND a.tags LIKE '%Barber Shop%' ORDER BY b.gal_rating_sum DESC LIMIT 0 ,10
) queryA
left join
(
SELECT zip_code ,( 3959 * acos( cos( radians('41.97734070') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('-70.97234344') ) + sin( radians('41.97734070') ) * sin( radians( latitude ) ) ) ) AS distance FROM city_finder WHERE latitude IS NOT NULL AND longitude IS NOT NULL HAVING distance < 20 ORDER BY distance ASC
) queryB
on queryA.zip=queryB.zip_code
proper formatting
SELECT *
FROM
( SELECT a.*
FROM modzzz_listing_main AS a
LEFT JOIN modzzz_listing_rating AS b ON a.id=b.gal_id
WHERE LTRIM(a.city) = 'Houston'
AND a.state = 'TX'
AND a.tags LIKE '%Barber Shop%'
ORDER BY b.gal_rating_sum DESC LIMIT 0 ,
10 ) queryA
LEFT JOIN
( SELECT zip_code ,
(3959 * acos(cos(radians('41.97734070')) * cos(radians(latitude)) * cos(radians(longitude) - radians('-70.97234344')) + sin(radians('41.97734070')) * sin(radians(latitude)))) AS distance
FROM city_finder
WHERE latitude IS NOT NULL
AND longitude IS NOT NULL HAVING distance < 20
ORDER BY distance ASC ) queryB ON queryA.zip=queryB.zip_code
I have 3 tables
tblMarkers
tblReviews
tblImages
I want to return ALL the records from tblMarkers and a count of all the reviews and images for each marker.
To complicate it further it should return all the markers within a radius of a known point.
so the expected result would be
MarkerID-MarkerName-ReviewCount-ImageCount
1223-SomeName-0-1
This is what I have so far and this returns a count of reviews, but I cant get the right SQL to add the count of images
SELECT
`tblMarkers`.`ID`,
`tblMarkers`.`Type`,
`tblMarkers`.`Name`,
`tblMarkers`.`Latitude`,
`tblMarkers`.`Longitude`,
(3959 * acos( cos( radians('45.1') ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians('6') ) + sin( radians('45.1') ) * sin( radians( Latitude ) ) ) )
AS distance,
Count(`tblReviews`.`marker_id`) As reviewCount
FROM
`tblMarkers`
LEFT JOIN `tblReviews` ON `tblMarkers`.`ID` = `tblReviews`.`marker_id`
GROUP BY
`tblMarkers`.`ID`,
`tblMarkers`.`Type`,
`tblMarkers`.`Name`,
`tblMarkers`.`Latitude`,
`tblMarkers`.`Longitude`
HAVING
`distance` < '50'
ORDER BY
distance;
The Images table structure is
ID [primaryKey] (same as tblMarkers.ID)
file
title
How do I add a count of all the images?
Try this:
SELECT M.ID
, M.Type
, M.Name
, M.Latitude
, M.Longitude
, (3959 * acos(cos(radians('45.1')) * cos(radians(M.Latitude )) * cos(radians(M.Longitude) - radians('6')) + sin(radians('45.1')) * sin(radians(M.Latitude )))) AS distance
, IFNULL(COUNT(DISTINCT R.review_id) , 0) AS ReviewCount
, IFNULL(COUNT(DISTINCT I.ID), 0) AS ImageCount
FROM tblMarkers AS M
LEFT JOIN tblReviews AS R ON R.marker_id = M.ID
LEFT JOIN tblImages AS I ON I.marker_id = M.ID
GROUP BY M.ID, M.Type, M.Name, M.Latitude, M.Longitude
HAVING distance < 50
ORDER BY distance
I bet you already know LEFT JOIN. So I used COUNT(DISTINCT R.review_id)) to count all distinct review id's (just make sure that review_id is unique). In case there are no corresponding review and image record for a specific marker record, I used IFNULL(XXX , 0) to display 0.
I used ALIASES to make your query clean and neat. Feel free to ask.
IF ID field of image table is the reference of marker table ID field then the query will be:
SELECT
`tblMarkers`.`ID`,
`tblMarkers`.`Type`,
`tblMarkers`.`Name`,
`tblMarkers`.`Latitude`,
`tblMarkers`.`Longitude`,
(3959 * acos( cos( radians('45.1') ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians('6') ) + sin( radians('45.1') ) * sin( radians( Latitude ) ) ) )
AS distance,
Count(`tblReviews`.`marker_id`) As reviewCount,
Count(`tblImage`.`ID`) As imageCount,
FROM
`tblMarkers`
LEFT JOIN `tblReviews` ON `tblMarkers`.`ID` = `tblReviews`.`marker_id`
LEFT JOIN `tblImage` ON `tblMarkers`.`ID` = `tblImages`.`ID`
GROUP BY
`tblMarkers`.`ID`,
`tblMarkers`.`Type`,
`tblMarkers`.`Name`,
`tblMarkers`.`Latitude`,
`tblMarkers`.`Longitude`
HAVING
`distance` < '50'
ORDER BY
distance;