Laravel中如何统计列特定数据?员工技能关联统计咨询
Laravel中统计技能对应员工数量的优化方案
先梳理你的代码和需求中的核心问题,再给出针对性的解决方案:
一、修正模型关联关系
你提到「一个员工可拥有多项技能」,但当前表结构(员工表含skill_id)是一个员工对应一个技能的一对多关系,和设计初衷不符。分两种场景处理:
场景1:保持当前表结构(员工单技能)
Employees模型的关联方法写错了,应改为belongsTo(员工属于一个技能):
class Employees extends Model { use HasFactory; protected $guarded = []; protected $table = 'employees'; // 修正关联:员工属于一个技能 public function Skill() { return $this->belongsTo(Skill::class, 'skill_id'); } }
Skill模型的关联方法建议改为复数Employees(),符合Laravel命名规范:
public function Employees() { return $this->hasMany(Employees::class, 'skill_id', 'id'); }
场景2:实现员工多技能(多对多关联)
如果要实现「一个员工多项技能」,需调整表结构:
- 创建中间表
employee_skill,包含字段:employee_id、skill_id(可设置联合主键) - 修正两个模型的多对多关联:
// Skill模型 class Skill extends Model { use HasFactory; protected $fillable = ['skill_name']; public function Employees() { return $this->belongsToMany(Employees::class, 'employee_skill'); } } // Employees模型 class Employees extends Model { use HasFactory; protected $guarded = []; protected $table = 'employees'; public function Skills() { return $this->belongsToMany(Skill::class, 'employee_skill'); } }
二、优化统计逻辑(避免N+1查询)
你当前的totalEmp()方法会触发N+1查询问题(每个技能单独执行一次count查询),用Laravel的withCount预加载统计是最优方案:
控制器预加载统计数据
无论哪种关联场景,都可以通过withCount过滤状态为1的员工:
// 一对多场景(当前表结构) $skills = Skill::withCount(['Employees' => function ($query) { $query->where('status', 1); }])->get(); // 多对多场景(员工多技能) $skills = Skill::withCount(['Employees' => function ($query) { $query->where('status', 1); }])->get();
视图直接调用统计结果
视图中无需再调用totalEmp(),直接使用Laravel自动生成的[关联名]_count字段:
<tbody> @foreach ($skills as $skill) <tr> <th scope="row">{{ $loop->index+1 }}</th> <td>{{ $skill->skill_name }}</td> <!-- 直接使用预加载的统计值 --> <td>{{ $skill->employees_count }}</td> <td style="width: 25%;"> <button class="btn btn-outline-danger" type="button" title="Delete Skill">Delete Skill</button> </td> </tr> @endforeach </tbody>
三、清理冗余代码
使用withCount后,Skill模型中的totalEmp()方法可以直接删除,减少代码冗余。
内容的提问来源于stack exchange,提问作者Wakil Ahmed
相关产品推荐
相关产品推荐

