What I'm trying to do is simple : - When a calculated distance depending on users latitude and longitude (on DB) is higher than an int, we remove the current user from result by adding a where - When that distance isn't higher, we add a custom value to the returned result
This can be easily done using a foreach AFTER the query is executed :
foreach($search as $key => $value){
if(distance($value->latitude,$value->longitude,$user->latitude,$user->longitude,"K") > $distance) {
unset($search[$key]);
} else {
$search[$key]->distance = $calculatedDistance
}
}
The cons of this way is that in case we have a large database, it will consume a lot of memory and time, as we do twice what should be done directly in query.
What I need to do is to make this executed on the query itself. What I don't know how to do is : - Adding a custom value to the query directly when query is executed, and to do the distance calculation inside a when in the query, without using a foreach but directly getting the current raw value to compare with.
What I'm doing now :
->when($distance > 0, function ($query) use($distance, $longitude, $latitude){
$query->where(function ($subQuery) use ($longitude, $latitude,$distance) {
$cDistance = distance((int)$subQuery->value('latitude'),
(int)$subQuery->value('longitude'),
$latitude,
$longitude,
"K");
$subQuery->when(($cDistance > $distance),
function ($subQuery){
$subQuery->where('users.id', '<>', (int)$subQuery->value('id'));
},function ($subQuery) use ($cDistance) {
$subQuery->value((string)$cDistance.' as distance');
}
);
});
$subQuery->value('something')
is only testing with the first raw of the query, and not doing this for all rows. $subQuery->value((string)$cDistance.' as distance');
is returning an error
SQLSTATE[42S22]: Column not found: 1054 Unknown column '84.354917445764' in 'field list' (SQL: select
84
.354917445764
asdistance
fromusers
limit 1)
$sqlDistance = DB::raw('ROUND ( 6371 * acos( cos( radians(' . $latitude . ') )
* cos( radians( doctor_profile.latitude ) )
* cos( radians( doctor_profile.longitude )
- radians(' . $longitude . ') )
+ sin( radians(' . $latitude . ') )
* sin( radians( doctor_profile.latitude ) ) ) )');
Inside the query :
->selectRaw("{$sqlDistance} AS distance")
->when($distance > 0, function ($query) use ($distance,$sqlDistance){
$query->havingRaw('{$sqlDistance} <= ?', [$distance]);
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.