Home > Mobile >  Is there any way to get two different results with single query based on condition?
Is there any way to get two different results with single query based on condition?

Time:05-20

I am trying to get two different results from single query but the problem is both conditions get applied on last query.

for example

$getUser = User::join('role_user','role_user.user_id','users.id')
        ->select('users.id','users.name','users.email','users.identity_status','users.email_verified_at','role_user.role_id')
        ->where('role_user.role_id',2)
        ->whereNotNull('users.email_verified_at');

$newMailUsers = $getUser->where('new_mail',0)->get();
            
$topSellingMailUsers = $getUser->where('topselling_mail',0)->get();

but when i checked sql query of $topSellingMailUsers i saw that both the conditions of new_mail and topselling_mail applied in $topSellingMailUsers query what i want is it should not consider mail condition in query.

how can i get two different results of $newMailUsers, $topSellingMailUsers based on both conditions separately.

CodePudding user response:

you need to clone Builder object to reuse it

$selectFields = [
  'users.id', 
  'users.name', 
  'users.email', 
  'users.identity_status', 
  'users.email_verified_at', 
  'role_user.role_id'
];
/** @var Illuminate\Database\Eloquent\Builder */
$getUser = User::join('role_user', 'role_user.user_id', 'users.id')
  ->select($selectFields)
  ->where('role_user.role_id', 2)
  ->whereNotNull('users.email_verified_at');

$newMailUsers = (clone $getUser)->where('new_mail', 0)->get();

$topSellingMailUsers = (clone $getUser)->where('topselling_mail', 0)->get();

CodePudding user response:

Every time you use where() method you are mutating $getUser query builder.

You can chain your query builder with clone() method and this will return another query builder with the same properties.

$getUser = User::join('role_user','role_user.user_id','users.id')
        ->select('users.id','users.name','users.email','users.identity_status','users.email_verified_at','role_user.role_id')
        ->where('role_user.role_id',2)
        ->whereNotNull('users.email_verified_at');

$newMailUsers = $getUser->clone()->where('new_mail',0)->get();
            
$topSellingMailUsers = $getUser->clone()->where('topselling_mail',0)->get();

CodePudding user response:

Well, if you have relations set up on models will be easier, but still can do it:

// Let's say you pass sometimes the role_id
$role_id = $request->role_id ?? null;
        
$getUser = User::join('role_user','role_user.user_id','users.id')
   ->select('users.id','users.name','users.email','users.identity_status','users.email_verified_at','role_user.role_id')
   // ->where('role_user.role_id',2) // replaced with ->when() method
   ->when($role_id, function ($query) use ($role_id){
       $query->where('role_user.role_id', $role_id);
   })
   ->whereNotNull('users.email_verified_at');

This way it will return users with ALL ROLES or if ->when(condition is TRUE) it will return users with the role id = $role_id.

You can use multiple ->when(condition, function(){});

Have fun!

  • Related