Laravel同表嵌套关联查询:找出有子级但子级无子级的用户
实现方法:筛选有子级但子级无后代的用户
没问题,这个需求可以通过Laravel的关联查询方法组合来实现,我给你拆解思路和具体代码:
核心思路
我们需要筛选两类条件同时满足的用户:
- 该用户存在子级(通过
whereHas('children')判断) - 该用户的子级没有自己的子级(这里分两种场景,我都会覆盖到)
代码实现
场景1:用户至少有一个子级,且这个子级没有后代
如果你的需求是「只要用户有一个子级没有后代就算数」(不管他有没有其他子级有后代),用这段代码:
User::whereHas('children', function ($childQuery) { // 筛选出那些子级本身没有子级的情况 $childQuery->whereDoesntHave('children'); })->get();
场景2:用户所有子级都没有后代(用户是倒数第二层节点)
如果你的需求是「用户的所有子级都没有下一代」(也就是用户的孩子全是叶子节点),用这段代码:
User::whereHas('children') // 排除掉那些有子级且子级本身还有子级的用户 ->whereDoesntHave('children', function ($childQuery) { $childQuery->has('children'); }) ->get();
结合你的数据示例解释
看你的用户表数据:
id, uname, parent_id 1 john null 2 smith 1 3 mickey 1 4 lara 2 5 tom 3 6 jessica 4 7 baneet 4
- 场景1的查询结果会包含:
smith(他的子级lara有后代,但他确实有子级lara)、mickey(子级tom无后代)、lara(子级jessica和baneet都无后代) - 场景2的查询结果会是:
mickey、lara,而smith会被排除,因为他的子级lara有自己的后代。
小建议:关联关系命名优化
你的模型里parents()这个关联命名有点小问题,因为belongsTo是一对一关联(一个用户只能有一个父级),改成单数parent()会更符合Laravel的命名规范,可读性也更强:
public function parent() { return $this->belongsTo('App\Models\User', 'parent_id'); }
内容的提问来源于stack exchange,提问作者Baneet Kumar Sharma
相关产品推荐
相关产品推荐

