Exclude some rows from having condition - mysql

How can I exclude rows with show_all = '1' from HAVING clause?
SELECT
ID,
( 6371 * acos( cos( radians('". $lat ."') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('". $long ."') ) + sin( radians('". $lat ."') ) * sin( radians( lat ) ) ) ) AS distance
FROM events
WHERE active = '1'
AND closed = '0'
AND category IN ( '" . implode( "', '" , $styleArr ) . "' )
HAVING distance < 1000 AND distance > 0
ORDER BY events.start_date DESC
I don't want to apply HAVING condition if row's show_all = '1'

Change the HAVING clause to this:
HAVING (distance < 1000 AND distance > 0) OR show_all = '1'

Related

Pagination not working in Spring Boot Native Query

I have my pagination query I am passing page and size ass ?page=0&size=5. But not getting any result. This is my query.
#Query(
value = "SELECT *,
( 6371 * acos(
cos( radians(:lat) )
* cos( radians( latitude ) )
* cos( radians( longitude )
- radians(:lng) )
+ sin( radians(:lat) )
* sin( radians( latitude ) ) )
) AS distance
FROM stores
WHERE deleted = '0'
HAVING distance < 20000
ORDER BY distance ?#{#pageable}",
countQuery = "select count(*) from stores where deleted = 0",
nativeQuery = true)
public Page<Stores> getAllNearbyStores(
#Param("lat") double lat,
#Param("lng") double lng,
Pageable pageable
);
Error : You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near
'_binary'¬í\0sr\0+org.springframework.data.domain.PageRequestÀùPÅÀÇ&\0'
at line 1
there need to add \n-- #pageable\n instead of ?#{#pageable}
Query:
#Query(
value = "SELECT *,
( 6371 * acos(
cos( radians(:lat) )
* cos( radians( latitude ) )
* cos( radians( longitude )
- radians(:lng) )
+ sin( radians(:lat) )
* sin( radians( latitude ) ) )
) AS distance
FROM stores
WHERE deleted = '0'
HAVING distance < 20000
ORDER BY distance \n-- #pageable\n",
countQuery = "select count(*) from stores where deleted = 0",
nativeQuery = true)
public Page<Stores> getAllNearbyStores(
#Param("lat") double lat,
#Param("lng") double lng,
Pageable pageable
);
you can get details here
#Query(
value = "SELECT *,
( 6371 * acos(
cos( radians(:lat) )
* cos( radians( latitude ) )
* cos( radians( longitude )
- radians(:lng) )
+ sin( radians(:lat) )
* sin( radians( latitude ) ) )
) AS distance
FROM stores
WHERE deleted = '0'
HAVING distance < 20000
ORDER BY distance \n-- #pageable\n",
countQuery = "select count(*) from stores where deleted = 0",
nativeQuery = true)
public Page<Stores> getAllNearbyStores(
#Param("lat") double lat,
#Param("lng") double lng,
#PageableDefault(size = 5) Pageable pageable
);
There need to add default size to **#PageableDefault(size = 5). This solved the issue.

Find a partial match in MySQL query with multiple "OR"

I need to find partial or full matches in a MySQL query. I am performing queries in multiple tables using 'OR' and need to know whether all conditions have been met or just some of them.
I believe the easiest way to do this would be to create a new column called 'partial' which would either be 0 or 1 (Feel free to correct me if I am wrong).
Here is my query:
SELECT
id, confirmed, name, addressLine1, addressLine2, addressCity, addressPostcode,
addressLat, addressLon,
(6371 * acos( cos( radians( '53.649779' ) )
* cos( radians( addressLat ) )
* cos( radians( addressLon ) - radians( '-1.6026266' ) )
+ sin( radians( '53.649779' ) ) * sin( radians( addressLat ) ) )
) distance
FROM TABLE_NAME
WHERE active = '1'
AND deleted = '0'
AND
(
id < 0
OR
id IN
(
SELECT establishmentID
FROM appEstablishmentDrinks
WHERE active = '1'
AND deleted = '0'
AND manufacturerDrinkID IN (101)
GROUP BY establishmentID
HAVING count(distinct manufacturerDrinkID) = 1
)
OR
id IN
(
SELECT establishmentID
FROM appEstablishmentFacilities
WHERE active = '1'
AND deleted = '0'
AND facilityID IN (37)
)
)
HAVING distance < '15'
In MySQL true = 1 and false = 0. So simply add conditions: (id < 0) + (id in (...)) + (id in (...)) and check whether you got all three matches or less.
SELECT
id, confirmed, name, addressLine1, addressLine2, addressCity, addressPostcode,
addressLat, addressLon, distance,
case when count_matches = 3 then 'full' else 'partial' end as matching
FROM
(
SELECT
id, confirmed, name, addressLine1, addressLine2, addressCity, addressPostcode,
addressLat, addressLon,
(6371 * acos( cos( radians( 53.649779 ) )
* cos( radians( addressLat ) )
* cos( radians( addressLon ) - radians( -1.6026266 ) )
+ sin( radians( 53.649779 ) ) * sin( radians( addressLat ) ) )
) as distance,
(id < 0 )
+
(
id IN
(
SELECT establishmentID
FROM appEstablishmentDrinks
WHERE active = 1
AND deleted = 0
AND manufacturerDrinkID IN (101)
GROUP BY establishmentID
HAVING count(distinct manufacturerDrinkID) = 1
)
)
+
(
id IN
(
SELECT establishmentID
FROM appEstablishmentFacilities
WHERE active = 1
AND deleted = 0
AND facilityID IN (37)
)
) as count_matches
FROM TABLE_NAME
WHERE active = 1
AND deleted = 0
) x
WHERE distance < 15
AND count_matches > 0;

having clause in mysql query error

I am trying to the fetch nearest location according lat and lng but I want to add having distance < 5 clause in query.
But where I can use.??
select p.id, p.name, p_i.image as image,
( 3959 * acos( cos( radians(26.916279) ) *
cos( radians( lat ) ) *
cos( radians( lng ) - radians(75.8082) ) +
sin( radians(26.916279) ) *
sin( radians( lat ) ) ) ) AS distance
from `places` as p
inner join `place_images` as p_i
on p.`id` = p_i.`place_id`
where p.`city_id` = '1'
and p.status = 'active'
and p_i.display_order = '1'
limit 0, 5
current result
You can add having clause at last, just before limit
select p.id, p.name, p_i.image as image, ( 3959 * acos( cos( radians(26.916279) )
* cos( radians( lat ) ) * cos( radians( lng ) - radians(75.8082) )
+ sin( radians(26.916279) ) * sin( radians( lat ) ) ) ) AS distance
from `places` as p inner join `place_images` as p_i on p.`id` = p_i.`place_id`
where p.`city_id` = '1' and p.status = 'active' and p_i.display_order = '1'
HAVING distance < 5 limit 0, 5
Try this query
where p.`city_id` = '1' and p.status = 'active'
and p_i.display_order = '1'
HAVING distance < 5
limit 0, 5
use limit at last
select p.id, p.name, p_i.image as image, ( 3959 * acos( cos( radians(26.916279) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(75.8082) ) + sin( radians(26.916279) ) * sin( radians( lat ) ) ) ) AS distance from `places` as p inner join `place_images` as p_i on p.`id` = p_i.`place_id`
where p.`city_id` = '1'
and p.status = 'active'
and p_i.display_order = '1'
HAVING distance < 5 # add this
limit 0, 5

Merging 2 sql queries into a single one

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

Distinct not working properly

I've wrote a query with DISTINCT but I still get duplicate records returned.
SELECT DISTINCT
`cuisine_types`.`id`,
`cuisine_types`.`name`,
`cuisine_types`.`image`,
(
SELECT group_concat(`tagname` separator ', ')
FROM `cuisine_tags`
WHERE `cuisine_type` = `cuisine_types`.`id`
) AS tags,
(
3959 * acos( cos( radians(" . $dLat . ") ) * cos( radians( gps_lat ) ) * cos( radians( gps_lon ) - radians(" . $dLon . ") ) + sin( radians(" . $dLat . ") ) * sin( radians( gps_lat ) ) )
) AS distance
FROM `company`
LEFT JOIN `cuisine_types`
ON
`company`.`cuisine_type_id` = `cuisine_types`.`id`
HAVING
distance < " .$dMiles
When I try using the GROUP BY function my query isn't working properly.
When I use GROUP BY I place it above my HAVING:
GROUP BY `cuisine_types`.`name`
Examples:
When I use it with these values:
$dLat = '52.779716';
$dLon = '21.84803';
$iKm = '30';
It returns:
id = 1
name = Snackbar
image =
tags = Patat, Snacks
distance = 17.4713944772963
When I use $iKm with 3000 it returns this row as well:
id = 1
name = Snackbar
image =
tags = Patat, Snacks
distance = 722.407714147792
So I get two records.
When I use this with groupby and $iKm = 30; It returns nothing. With a value of 3000 it returns one row. But I have one record with a distance of 17 miles so thats below 30.
This should fix your problem, the issue was the distance calculation blocked the GROUP BY function. By putting the equation in the HAVING itself, the problem seemed to be fixed. Sorry I can't explain it in more detail.
SELECT
`cuisine_types`.`name`,
`cuisine_types`.`id`,
`cuisine_types`.`image`
`c`.`gps_lat` as lat,
`c`.`gps_lon` as lon,
(SELECT group_concat(`tagname` separator ', ') FROM `cuisine_tags` WHERE `cuisine_type`=`cuisine_types`.`id`) as tags FROM `company` as c LEFT JOIN `cuisine_types` ON c.`cuisine_type_id`
= `cuisine_types`.`id` GROUP BY `cuisine_types`.`name` HAVING ( 3959 * acos( cos( radians(52.779716) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(21.84803) ) + sin( radians(52.779716) ) * sin( radians( lat ) ) ) ) < 2000;