You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将原生SQL转换为Laravel查询构造器?求助解决查询无结果问题

问题:将原生SQL转换为Laravel查询构造器代码

我需要把下面的原生SQL转换成Laravel查询构造器代码,请求帮忙:

SELECT id, `leave_name`, `total_leave_days`, leave_id, leave_taken_days FROM `leaves` AS t1 INNER JOIN ( SELECT leave_id, SUM(`leave_taken_days`) AS leave_taken_days FROM `leave_applications` WHERE user_id = 2 AND statuses_id = 2 GROUP BY leave_id ) AS t2 ON t1.id = t2.leave_id

我自己试了下面的代码,但完全没有输出结果:

$user_leaves = DB::table('leaves')
        ->select('id', 'leave_name', 'total_leave_days', 'leave_id', 'leave_taken_days')
        ->join('leave_application', 'leave_application.leave_id', '=', 'leave.id')
        ->select('leave_application.leave_id', DB::raw("SUM(leave_taken_days) as leave_application.leave_taken_days"))
        ->where('user_id','=', 2)
        ->where('statuses_id','=', 2)
        ->get();

更新:模型关联关系

  • Leave模型
public function leave_application()
{
    return $this->belongsTo(LeaveApplication::class, 'id' , 'leave_id');
}
  • LeaveApplication模型
public function leave()
{
    return $this->belongsTo(Leave::class, 'leave_id', 'id');
}

解决方案

方法一:还原原生SQL的子查询关联逻辑

直接用Laravel的joinSub方法实现原生SQL的子查询关联逻辑,代码如下:

// 先定义子查询:统计符合条件的各假期类型已使用天数
$subQuery = DB::table('leave_applications')
    ->select('leave_id', DB::raw('SUM(leave_taken_days) as leave_taken_days'))
    ->where('user_id', 2)
    ->where('statuses_id', 2)
    ->groupBy('leave_id');

// 主表关联子查询获取最终数据
$user_leaves = DB::table('leaves as t1')
    ->select('t1.id', 't1.leave_name', 't1.total_leave_days', 't2.leave_id', 't2.leave_taken_days')
    ->joinSub($subQuery, 't2', function ($join) {
        $join->on('t1.id', '=', 't2.leave_id');
    })
    ->get();

方法二:修正模型关联后用关联查询实现

首先纠正你的模型关联逻辑:一个假期类型对应多个申请记录,所以Leave和LeaveApplication是一对多关系,关联定义需要修改:

  • Leave模型
public function leaveApplications()
{
    return $this->hasMany(LeaveApplication::class, 'leave_id', 'id');
}
  • LeaveApplication模型
public function leave()
{
    return $this->belongsTo(Leave::class, 'leave_id', 'id');
}

修正后,用关联查询+聚合的方式实现需求:

$user_leaves = Leave::query()
    ->select('leaves.id', 'leaves.leave_name', 'leaves.total_leave_days', DB::raw('SUM(leave_applications.leave_taken_days) as leave_taken_days'))
    ->join('leave_applications', 'leaves.id', '=', 'leave_applications.leave_id')
    ->where('leave_applications.user_id', 2)
    ->where('leave_applications.statuses_id', 2)
    ->groupBy('leaves.id', 'leaves.leave_name', 'leaves.total_leave_days')
    ->get();

你的代码问题分析

  1. 表名错误:原生SQL中是leave_applications,你写成了leave_application,导致关联的表不存在
  2. 重复select覆盖字段:连续调用select()会替换之前的字段选择,最终只保留最后一次的字段,主表的id、leave_name等字段无法被查询
  3. 逻辑不符:原生SQL是先对子表聚合分组再关联,你的代码直接join后聚合,缺少分组操作且逻辑不一致

内容的提问来源于stack exchange,提问作者Jhyaps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:05:22