Pagination not working in Spring Boot Native Query - mysql

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.

Related

How to write SQL JOIN query with geolocation in php

I am new to sql.
Sample of offerings Table
offering_id | offering_meal_id | offering_name | offering_profile_id | Offering_Expiration_Date_Time | Lat | Lon
Sample of profile Table
profile_id | fullname
I am passing following parameters $latitude , $longitude, $meal_id
I want to write a query which will
get all data from offerings table in basis of latitude and longitude and Offering_Expiration_Date_Time is greater than or equal to today's date. For this I have following calculation which is working.
SELECT *, ( 6371 * ACOS( COS( RADIANS( ".$latitude." ) ) *
COS( RADIANS( Lat ) ) * COS( RADIANS( Lon ) - RADIANS( ".$longitude." ) ) + SIN( RADIANS( ".$latitude." ) )
* SIN( RADIANS( Lat ) ) ) ) AS distance FROM offerings HAVING distance < 3 AND Offering_Expiration_Date_Time>='".date('Y-m-d h:i:s')."'
Next Select only those offering which meal_id = $meal_id
Join profile table and get fullname from it where offerings.offering_profile_id = profile.profile_id
order it by offering_id
EDIT
SELECT offerings.*,profile.fullname,
( 6371 * ACOS( COS( RADIANS( 16.691120 ) ) * COS( RADIANS( Lat ) ) * COS( RADIANS( Lon ) - RADIANS( 74.219978 ) ) + SIN( RADIANS( 16.691120 ) ) * SIN( RADIANS( Lat ) ) ) )
AS distance
FROM offerings
INNER JOIN profile
ON offerings.offering_profille_id = profile.profile_id
WHERE distance < 3
AND offerings.offering_meal_id = 2
AND Offering_Expiration_Date_Time>='2017-08-23 15:43:00'
ORDER BY offerings.offering_id
LIMIT 10
Before your having clause, join to the profile table like so:
Inner join profile on offerings.offering_profile_id = profile.profile_id
Then include at end:
Order by offerings.offering_id
Also make sure to include in your select statement
Profile.fullname
Also change having to where and add this into your where condition:
And offerings.offering_meal_id = $meal_id

MySQL - Find points within radius from database

I have a table which has a POINT column containing the latitude and longitude of various locations.
I then also have a users location from geo-location in the browser.
What I need to be able to do is find all records from the table where the POINT value in the is within a 10 km radius (or X km radius), ordered by distance with the closest first.
My table has a SPATIAL index on the POINT column.
I'm currently working on a project where I'm calculating distances between multiple locations. I'm using the following query for selecting object_id's which are within a given radius.
SELECT id,
( 6371 *
ACOS(
COS( RADIANS( db_latitude ) ) *
COS( RADIANS( $user_latitude ) ) *
COS( RADIANS( $user_longitude ) -
RADIANS( db_longitude ) ) +
SIN( RADIANS( db_latitude ) ) *
SIN( RADIANS( $user_latitude) )
)
)
AS distance FROM the_table HAVING distance <= $the_radius ORDER BY distance ASC"
I can't explain the ACOS formula itself because I got it from research.
db_latitude = database latitude field
db_longitude = database longitude field
$user_latitude = browser latitude coördinate
$user_longitude = browser longitude coördinate
$the_radius = the radius that you want to search in
This is in kilometers.
The query below actually worked for me :
$query = "SELECT *,
( 6371 *
acos(
cos( radians( ".$user_lat." ) ) *
cos( radians( lat ) ) *
cos( radians( lng ) -
radians( ".$user_lng." ) ) +
sin( radians( ".$user_lat." ) ) *
sin( radians( lat ) ) ) )
AS distance FROM parkings
HAVING distance <= ".$radius." ORDER BY distance ASC";
$stmt = $conn->execute($query);
$rows = $stmt->fetchAll('assoc');
where:
$user_lat and $user_lng is browser's lat and lng,
$radius = 10,
table name is parkings
May be this help for you,
https://ru.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL
For Django I use this
dist = 20 #дистанция 20 км
mylon = 51.5289156201 # долгота центра
mylat = 46.0209384922 # широта
lon1 = mylon-dist/abs(math.cos(math.radians(mylat))*111.0) # 1 градус широты = 111 км
lon2 = mylon+dist/abs(math.cos(math.radians(mylat))*111.0)
lat1 = mylat-(dist/111.0)
lat2 = mylat+(dist/111.0)
profiles = UserProfile.objects.filter(lat__range=(lat1, lat2)).filter(lon__range=(lon1, lon2))
It search all users in squar 20km.

Virtual column unknown when comparing lat lng

I am attempting to return only rows where the latitude and longitude being passed into the query, when compared to the latitude and longitude stored in the database, is a certain amount of miles apart.
The query is as follows:
SELECT
c.google_theatre_id
AS cinema_id,
c.name
AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) ) )
AS distance
FROM
google_cinemas c, app_users u
WHERE
distance < u.range
AND
u.id = 126
ORDER BY
distance
The query is designed to get the distance and then compare it to a column (range) in the app_users table.
When running the query, I'm getting an error of distance being an unknown column.
As this is a virtual column, is there a different way of comparing?
Thanks :)
you need to use HAVING instead of WHERE.. think of it this way WHERE is when you make an order at a restraunt and HAVING is picking stuff off of the plate when it comes to your table... you cannot reference an alias before the plate comes to your table only after it has been built
SELECT
c.google_theatre_id AS cinema_id,
c.name AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) )
) AS distance
FROM google_cinemas c, app_users u
WHERE u.id = 126
HAVING distance < u.range
ORDER BY distance
alternatively you can use it as a sub query which could be faster since HAVING re-evaluates the entire query.
SELECT *
FROM
( SELECT
c.google_theatre_id AS cinema_id,
c.name AS cinema_name,
( 3959 * acos( cos( radians('50.4521013') ) *
cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('-3.5247389') ) +
sin( radians('50.4521013') ) *
sin( radians( latitude ) ) )
) AS distance,
u.range
FROM google_cinemas c, app_users u
WHERE u.id = 126
ORDER BY distance
)t
WHERE distance < range

SQL with Multiple Where Clauses

First -- I have read about 7 pages of posts with similar titles but couldn't find the right insight for my challenge
My SQL:
SELECT name, address, lat, lng, city, state, phone, zip, info
, ( 3959 * acos( cos( radians('37.4969') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('-122.2674') ) + sin( radians('37.4969') ) * sin( radians( lat ) ) ) ) AS distance
FROM myhealthfinder_map
HAVING distance < '50' and location = '2'
ORDER BY distance LIMIT 0 , 10
I get the error message: Invalid query: Unknown column 'location' in 'having clause'
if instead of HAVING I just make it WHERE location = '2' then it works fine [it finds the column] (but I need the distance selector).
Any suggestion on how to knock this down?
Use both WHERE and HAVING. HAVING is used for aggregated and calculated columns. And WHERE on plain old columns.
SELECT name, address, lat, lng, city, state, phone, zip, info
, ( 3959 * acos( cos( radians('37.4969') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('-122.2674') ) + sin( radians('37.4969') ) * sin( radians( lat ) ) ) ) AS distance
FROM myhealthfinder_map
WHERE location = '2'
HAVING distance < '50'
ORDER BY distance LIMIT 0 , 10
More explanation found here WHERE vs HAVING
Don't use HAVING without GROUP BY. You can try this instead
SELECT name, address, lat, lng, city, state, phone, zip, info, ( 3959 * acos( cos( radians('37.4969') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('-122.2674') ) + sin( radians('37.4969') ) * sin( radians( lat ) ) ) ) AS distance
FROM myhealthfinder_map
WHERE location = '2' AND
( 3959 * acos( cos( radians('37.4969') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('-122.2674') ) + sin( radians('37.4969') ) * sin( radians( lat ) ) ) ) < 50
ORDER BY distance LIMIT 0 , 10
It's not pretty, but it should work.

MySQL: Combining two queries into one row result

First part of the query:
SET #centerLat = '48.531157';
SET #centerLng = '-123.782959';
SELECT user_id, lat, lng, ( 3959 * acos( cos( radians( #centerLat ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(#centerLng) ) + sin( radians( #centerLat ) ) * sin( radians( lat ) ) ) ) AS distance FROM bid_userloc HAVING distance < 25 ORDER BY distance LIMIT 0 , 20
Second aspect is taking the user_id and grabbing a bunch of information from the USERS table
I'm still learning what JOIN even means and I don't quite understand how it all works best...
you may try this
SELECT user_id, lat, lng, ( 3959 * acos( cos( radians( #centerLat ) )
* cos( radians( lat ) ) * cos( radians( lng ) - radians(#centerLng) )
+ sin( radians( #centerLat ) ) * sin( radians( lat ) ) ) )
AS distance,columnsfromuserstable FROM bid_userloc bid
inner join users us on bid.user_id=us.user_id
HAVING distance < 25
ORDER BY distance LIMIT 0 , 20
You can try something like this:
select * from users where user_id in (select user_id from(
SELECT user_id, lat, lng, ( 3959 * acos( cos( radians( #centerLat ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(#centerLng) ) + sin( radians( #centerLat ) ) * sin( radians( lat ) ) ) ) AS distance FROM bid_userloc HAVING distance < 25 ORDER BY distance LIMIT 0 , 20
));
Variant with JOIN -
SET #centerLat = '48.531157';
SET #centerLng = '-123.782959';
SELECT
t1.user_id, t1.lat, t1.lng,
(3959 * ACOS(COS(RADIANS(#centerLat)) * COS(RADIANS(t1.lat)) * COS(RADIANS(t1.lng) - RADIANS(#centerLng)) + SIN(RADIANS(#centerLat)) * SIN(RADIANS(t1.lat)))) distance,
t2.*
FROM
bid_userloc t1
JOIN users t2
ON t1.user_id = t2.user_id
HAVING
distance < 25
ORDER BY
distance
LIMIT
0, 20;