Laravel 5.4:原生SQL转Eloquent查询遇阻,请求协助
没问题!我帮你把这段原生SQL转换成Laravel 5.4兼容的Eloquent查询,下面提供两种贴合你需求的实现方式,你可以根据实际场景选择:
方式一:完全匹配原生SQL的子查询Join逻辑
这种写法和你原生SQL的执行逻辑完全一致,通过子查询关联每个项目的最新进度记录,再进行条件过滤:
use Carbon\Carbon; use Illuminate\Support\Facades\DB; // 构造子查询:获取每个项目对应的最新进度记录ID $latestProgressSubquery = function ($query) { $query->select('id') ->from('project_progress') ->whereColumn('project_id', 'projects.id') ->orderBy('created_at', 'desc') ->limit(1); }; // 主查询 $projects = Project::join('project_progress', 'project_progress.id', '=', DB::raw("({$latestProgressSubquery->toSql()})")) ->mergeBindings($latestProgressSubquery) // 绑定子查询参数,避免SQL注入 ->where('project_progress.next_action_date', '<', Carbon::now()) ->where('projects.status', '!=', 'Complete') // 补充你未写完的`projects.mem...`条件,例如:->where('projects.member_id', '=', $targetMemberId) ->select('projects.*', 'project_progress.*') // 按需选择字段,避免重复字段冲突 ->get();
方式二:利用模型关联简化查询
先在Project模型中定义一个关联最新进度的方法,后续查询会更简洁:
第一步:定义模型关联
// app/Project.php class Project extends Model { // 关联项目的最新进度记录 public function latestProgress() { return $this->hasOne(ProjectProgress::class)->latest('created_at'); } }
第二步:执行查询
如果需要同时获取项目数据和最新进度数据,可以用预加载+关联过滤的方式:
use Carbon\Carbon; $projects = Project::with('latestProgress') ->where('status', '!=', 'Complete') ->whereHas('latestProgress', function ($query) { $query->where('next_action_date', '<', Carbon::now()); }) // 补充你未写完的`projects.mem...`条件 ->get();
如果更倾向于用Join逻辑(和原生SQL更贴近),也可以这样写:
use Carbon\Carbon; $projects = Project::join('project_progress', function ($join) { $join->on('project_progress.id', '=', function ($query) { $query->select('id') ->from('project_progress') ->whereColumn('project_id', 'projects.id') ->orderBy('created_at', 'desc') ->limit(1); }); }) ->where('project_progress.next_action_date', '<', Carbon::now()) ->where('projects.status', '!=', 'Complete') // 补充你未写完的`projects.mem...`条件 ->select('projects.*', 'project_progress.*') ->get();
小提示
如果project_progress表的id是自增主键,你可以用MAX(id)代替orderBy('created_at', 'desc')->limit(1)来获取最新记录,子查询的执行效率会更高:
$latestProgressSubquery = function ($query) { $query->select(DB::raw('MAX(id)')) ->from('project_progress') ->whereColumn('project_id', 'projects.id'); };
内容的提问来源于stack exchange,提问作者Physik
相关产品推荐
相关产品推荐

