首页 > 解决方案 > Laravel - 离开计数查询没有给出想要的结果

问题描述

我正在使用 Laravel-5.8 来获取已申请休假和未申请特定年份的员工的数量。

我有这 3 个表:hr_employees、hr_departments 和 hr_leave_requests。

class HrDepartment extends Model
{
    protected $table = 'hr_departments';
    protected $fillable = [
        'id',
        'company_id',
        'dept_name',
    ];
}
class HrEmployee extends Model
{
    protected $table = 'hr_employees';
    protected $fillable = [
        'id',
        'company_id',
        'first_name',
        'last_name',
        'department_id',
    ];
    public function department()
    {
        return $this->belongsTo('App\Models\Hr\HrDepartment', 'department_id', 'id');
    }  
}
class HrLeaveRequest extends Model
{
    protected $table = 'hr_leave_requests';
    protected $fillable = [
        'id',
        'company_id',
        'leave_status',
        'employee_id',
    ];
    public function department()
    {
        return $this->belongsTo('App\Models\Hr\HrDepartment', 'department_id', 'id');
    }  
}

员工一年内可以申请多次休假,但算作一次。一个部门有很多员工。下面是我的代码:

$leaveReports = DB::table('hr_departments AS d')
    ->leftJoin('hr_employees AS e', function ($join) use ($userCompany) {
        $join->on('d.id', '=', 'e.department_id')
             ->where('e.company_id', '=', $userCompany)
             ->where('e.hr_status', '=', '0');
    })
    ->join('hr_leave_requests AS lr', function ($join) use ($userCompany) {
        $join->on('e.id', '=', 'lr.employee_id')
             ->where('lr.company_id', '=', $userCompany)
             ->where('lr.leave_status', '!=', '0');
    })
    ->where('d.company_id', '=', $userCompany)
    ->select(
        'd.dept_name',
        DB::raw('COUNT("lr.id") as applied_count'),
    )
    ->groupby('lr.employee_id')
    ->get();

我想在下面显示结果:

休假计数

我想列出所有部门,统计申请休假和未申请休假的员工人数。如果 leave_status 不为 0,则employee_id 已申请请假。要在某个部门申请,请从该部门的员工总数中减去该部门的申请总数。

如果我有 3 个部门和 50 名员工。它显示所有部门并显示每个部门已申请和未申请的计数

但是,它没有在图表中获取结果类型,而是将所有员工计算为应用总数。

我该如何解决这个问题?

谢谢

标签: laravel

解决方案


选项 1:雄辩的关系。

您可以使用该withCount方法来做到这一点。但为此,您需要首先在 HrDepartment 模型中定义关系。

class HrDepartment extends Model
{
    protected $table = 'hr_departments';
    protected $fillable = [
        'id',
        'company_id',
        'dept_name',
    ];
    public function employees()
    {
        return $this->hasMany('App\Models\HrEmployee', 'department_id', 'id');
    }
    public function leave_requests()
    {
        return $this->hasManyThrough('App\Models\HrLeaveRequest', 'App\Models\HrEmployee', 'department_id', 'employee_id');
    }
}
$departments = HrDepartment::select('hr_departments.dept_name')
    ->withCount([
        'leave_requests as total_applied' => function ($query) {
            $query->where('hr_leave_requests.leave_status', '=', 0);
        },
        'leave_requests as total_not_applied' => function ($query) {
            $query->where('hr_leave_requests.leave_status', '!=', 0);
        },
    ])
    ->where('hr_departments.company', '=', $userCompany)
    ->get();

选项 2:查询生成器

您可以通过在基本查询构建器中复制和粘贴 eloquent 的查询来获得相同的结果,但相比之下它看起来并不漂亮。

$departments = DB::table('hr_departments as d')
    ->select([
        'd.dept_name',
        'total_applied' => function ($query) {
            $query->from('hr_leave_requests as lr')
                  ->join('hr_employees as e', 'e.id', 'lr.employee_id')
                  ->selectRaw('count(*)')
                  ->whereColumn('d.id', 'e.department_id')
                  ->where('lr.leave_status', '=', 0);
        },
        'total_not_applied' => function ($query) {
            $query->from('hr_leave_requests as lr')
                  ->join('hr_employees as e', 'e.id', 'lr.employee_id')
                  ->selectRaw('count(*)')
                  ->whereColumn('d.id', 'e.department_id')
                  ->where('lr.leave_status', '!=', 0);
        }
    ])
    ->where('d.company', '=', $userCompany)
    ->get();

推荐阅读