有什么方法可以根据条件通过单个查询获得两个不同的结果?
Is there any way to get two different results with single query based on condition?
我试图从单个查询中获得两个不同的结果,但问题是这两个条件都应用于最后一个查询。
例如
$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();
但是当我检查 sql $topSellingMailUsers 的查询时,我看到 new_mail 和 topselling_mail 的条件都应用于 $topSellingMailUsers 查询,我想要的是它不应该考虑邮件查询中的条件。
我怎样才能分别根据这两个条件获得 $newMailUsers、$topSellingMailUsers 的两个不同结果。
您需要克隆 Builder 对象才能重用它
$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();
每次使用 where()
方法时,您都在改变 $getUser
查询构建器。
您可以使用 clone()
方法链接您的查询构建器,这将 return 另一个具有相同属性的查询构建器。
$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();
好吧,如果你在模型上建立关系会更容易,但还是可以做到:
// 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');
这样它将 return 具有 ALL ROLES 的用户,或者如果 ->when(condition is TRUE) 它将 return 具有角色 id = $role_id.[= 的用户11=]
您可以使用多个 ->when(condition, function(){});
玩得开心!
除了触发多个查询之外,您还可以使用如下所示的收集方法在单个查询中执行此操作。
$users = 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', 'new_mail', 'topselling_mail')
->where('role_user.role_id',2)
->where(function($query) {
$query->where('new_mail', 0)->orWhere('topselling_mail', 0);
})
->whereNotNull('users.email_verified_at')
->get();
$newMailUsers = $users->where('new_mail',0)->get();
$topSellingMailUsers = $user->where('topselling_mail',0)->get();
我试图从单个查询中获得两个不同的结果,但问题是这两个条件都应用于最后一个查询。
例如
$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();
但是当我检查 sql $topSellingMailUsers 的查询时,我看到 new_mail 和 topselling_mail 的条件都应用于 $topSellingMailUsers 查询,我想要的是它不应该考虑邮件查询中的条件。
我怎样才能分别根据这两个条件获得 $newMailUsers、$topSellingMailUsers 的两个不同结果。
您需要克隆 Builder 对象才能重用它
$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();
每次使用 where()
方法时,您都在改变 $getUser
查询构建器。
您可以使用 clone()
方法链接您的查询构建器,这将 return 另一个具有相同属性的查询构建器。
$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();
好吧,如果你在模型上建立关系会更容易,但还是可以做到:
// 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');
这样它将 return 具有 ALL ROLES 的用户,或者如果 ->when(condition is TRUE) 它将 return 具有角色 id = $role_id.[= 的用户11=]
您可以使用多个 ->when(condition, function(){});
玩得开心!
除了触发多个查询之外,您还可以使用如下所示的收集方法在单个查询中执行此操作。
$users = 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', 'new_mail', 'topselling_mail')
->where('role_user.role_id',2)
->where(function($query) {
$query->where('new_mail', 0)->orWhere('topselling_mail', 0);
})
->whereNotNull('users.email_verified_at')
->get();
$newMailUsers = $users->where('new_mail',0)->get();
$topSellingMailUsers = $user->where('topselling_mail',0)->get();