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

Laravel 5.5中如何用Eloquent实现含NOT BETWEEN的关联查询

用Laravel Eloquent实现目标SQL查询

没问题,我来帮你把这段原生SQL转换成纯Eloquent的写法,既保留原逻辑,又符合Laravel的优雅风格:

首先回顾下你的目标SQL:

select * from users inner join settings on users.id = settings.user_id and NOW() NOT BETWEEN quit_hour_start AND quit_hour_end where notification_key != '' and device_type = 'Android'

下面是对应的Eloquent实现:

$androidUsers = User::join('settings', function ($join) {
    // 先指定外键关联的ON条件
    $join->on('users.id', '=', 'settings.user_id')
         // 再添加ON子句里的额外时间条件
         ->whereRaw('NOW() NOT BETWEEN settings.quit_hour_start AND settings.quit_hour_end');
})
// 添加WHERE子句的两个过滤条件
->where('notification_key', '!=', '')
->where('device_type', 'Android')
// 获取结果集
->get();

一些补充说明:

  • 这里用join()的闭包形式来定义JOIN的完整ON条件,因为原SQL的ON子句除了外键关联,还有额外的时间判断,闭包能清晰地把这两个条件都放到ON里面,和原生SQL逻辑完全一致。
  • whereRaw()用来嵌入NOW() NOT BETWEEN...这段原生数据库语法,因为Eloquent查询构造器没有直接对应BETWEEN的反向判断方法,用原生片段是最直接的方式。
  • 如果你想避免select *带来的字段冗余或冲突,可以手动指定需要查询的字段,比如:
    ->select('users.id', 'users.name', 'settings.quit_hour_start', 'settings.notification_key')
    
  • 如果你已经在User模型中定义了和Setting的关联(比如public function settings() { return $this->hasOne(Setting::class); }),也可以用whereHas来实现,但直接用join在这个场景下更高效,和原SQL的执行逻辑完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:37:58