Laravel 5.5中如何用Eloquent实现含NOT BETWEEN的关联查询
用Laravel Eloquent实现目标SQL查询
没问题,我来帮你把这段原生SQL转换成纯Eloquent的写法,既保留原逻辑,又符合Laravel的优雅风格:
首先回顾下你的目标SQL:
select * from
usersinner joinsettingsonusers.id=settings.user_idand NOW() NOT BETWEEN quit_hour_start AND quit_hour_end wherenotification_key!= '' anddevice_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
相关产品推荐
相关产品推荐

