Laravel不使用Join关联两张表查询 将子查询SQL转为Eloquent查询
Laravel 无关联查询实现方案
方案1:子查询实现(与你提供的原生SQL完全等价)
可以直接用selectSub方法实现原生SQL中的子查询逻辑,不需要手动写RAW语句:
// 构造部门名称子查询 $dnameQuery = DB::table('dept') ->whereColumn('dept.deptno', 'emp.deptno') ->select('dname'); // 执行员工查询,关联子查询获取部门名称 $employees = DB::table('emp') ->select('ename') ->selectSub($dnameQuery, 'dname') ->get();
如果需要用模型类调用写法如下:
$dnameQuery = Dept::whereColumn('dept.deptno', 'emp.deptno')->select('dname'); $employees = Emp::select('ename')->selectSub($dnameQuery, 'dname')->get();
方案2:两次查询实现(大表场景性能更优,无任何关联操作)
针对你提到的employee表数据量大的场景,两次独立查询的性能远优于子查询和JOIN操作,实现逻辑如下:
- 第一步查询员工数据,提取所有关联的部门编号
- 第二步根据部门编号批量查询部门名称,生成编号-名称映射表
- 第三步遍历员工数据,手动赋值部门名称属性
// 1. 查询员工数据,可按需加分页、筛选条件 $employees = Emp::select('ename', 'deptno')->get(); // 分页场景替换为 $employees = Emp::select('ename', 'deptno')->paginate(20); // 2. 批量查询关联的部门数据,生成映射集合 $deptMap = Dept::whereIn('deptno', $employees->pluck('deptno')->unique()) ->pluck('dname', 'deptno'); // 3. 给员工数据追加部门名称属性 $employees->each(fn ($emp) => $emp->dname = $deptMap[$emp->deptno] ?? '');
内容的提问来源于stack exchange,提问作者insoftservice
相关产品推荐
相关产品推荐

