使用 AND、OR 和 IS NULL 进行高级连接 - Laravel

Sim*_*son 3 php mysql sql laravel laravel-4

我想创建一个这样的查询。

SELECT *
FROM user
INNER JOIN course ON user.course_id = course.id
AND (user.year_from IS NULL OR course.year_from > course.year_from)
AND (user.year_to IS NULL OR course.year_to < course.year_to)
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是我不知道如何翻译 IS NULL 部分。甚至有可能吗?第二个问题是如何使括号正确。我的第一个想法是做一些类似于高级 where 子句的事情。

$query->join('course', function($join) {
    $join->on(function($join) {
        $join->onNull('user.year_from')->orOn('user.year_from', '>', 'course.year_from');
    };
    $join->on(function($join) {
        $join->onNull('user.year_to')->orOn('user.year_to', '<', 'course.year_to');
    };
});
Run Code Online (Sandbox Code Playgroud)

但是JoinClouse该类没有方法 onNull 并且不支持将闭包作为参数传递。还有其他建议吗?

Jar*_*zyk 5

您无法使用 Laravel 方法创建精确的查询(当然除非使用 raw)。

以下是您所需要的:

$query->join('course', 'user.course_id', '=', 'course.id')
  ->where(function ($q) {
    $q->whereNull('user.year_from')->orWhere('user.year_from', '>', DB::raw('course.year_from'));
  })
  ->where(function ($q) {
    $q->whereNull('user.year_to')->orWhere('user.year_to', '<', DB::raw('course.year_to'));
  });
Run Code Online (Sandbox Code Playgroud)

这是 Laravel 可以处理您的查询的唯一方式,并且基本上完全相同。