简体   繁体   中英

Using Laravel QueryBuilder “when” and add a custom value to Query result

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 as distance from users 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM