Laravel中使用Eloquent实现含子查询Count的Where子句
解决Laravel Eloquent实现多匹配条件的查询问题
看起来你想要筛选出完全包含所有指定合作ID的律师,也就是每个律师对应的合作记录必须覆盖你传入的所有$request->cooprations项。你的原生SQL逻辑是对的,但用join的方式很难直接实现>=的计数判断,这里给你两种更合适的写法:
方法一:直接映射原生SQL的子查询写法
这种写法完全对应你给出的原生SQL,用Eloquent的子查询语法实现:
$cooprationIds = $request->cooprations; $requiredMatchCount = count($cooprationIds); // 确保传入的合作ID数组非空,避免SQL错误 if (empty($cooprationIds)) { // 这里可以根据业务需求返回空集合或者所有律师 return collect(); } $lawyers = \App\Models\Lawyer::from('tbl_lawyers as l') ->where(function ($subQuery) use ($cooprationIds) { // 子查询统计当前律师匹配的合作ID数量 return $subQuery->selectRaw('count(*)') ->from('cooprations as c') ->whereColumn('c.fk_lawyer_id', 'l.lawyer_id') ->whereIn('c.fk_coopration_id', $cooprationIds); }, '>=', $requiredMatchCount) ->get();
方法二:用whereHas关联查询(更优雅)
如果你的Lawyer模型已经定义了和Coopration的关联关系,这种写法更简洁:
首先在Lawyer模型中定义关联:
// app/Models/Lawyer.php public function cooprations() { return $this->hasMany(\App\Models\Coopration::class, 'fk_lawyer_id', 'lawyer_id'); }
然后直接用whereHas实现计数判断:
$cooprationIds = $request->cooprations; $requiredMatchCount = count($cooprationIds); if (empty($cooprationIds)) { return collect(); } $lawyers = \App\Models\Lawyer::whereHas( 'cooprations', function ($query) use ($cooprationIds) { $query->whereIn('fk_coopration_id', $cooprationIds); }, '>=', // 这里指定运算符 $requiredMatchCount // 需要匹配的数量 )->get();
为什么你的join写法不生效?
你原来用join的方式,会把每个匹配的合作记录和律师行进行关联,最终结果会是多条重复的律师数据(每个匹配的合作对应一行)。如果要通过join实现,需要先分组再用having,但写法会复杂很多:
// 不推荐的join写法(仅作对比) $lawyers = \App\Models\Lawyer::join('cooprations as c', 'c.fk_lawyer_id', '=', 'tbl_lawyers.lawyer_id') ->whereIn('c.fk_coopration_id', $cooprationIds) ->groupBy('tbl_lawyers.lawyer_id') ->havingRaw('count(DISTINCT c.fk_coopration_id) >= ?', [$requiredMatchCount]) ->get();
这种写法还要注意添加DISTINCT避免重复计数(如果同一个律师和同一个合作ID有多个记录的话),显然不如前两种方法直观。
内容的提问来源于stack exchange,提问作者faeze ravanbakhsh
相关产品推荐
相关产品推荐

