Laravel - 从一个表中获取不存在于另一个表中的记录,并附加了 where 子句

Posted

技术标签:

【中文标题】Laravel - 从一个表中获取不存在于另一个表中的记录,并附加了 where 子句【英文标题】:Laravel - Get records from one table that doesn't exist in another with a where clause attached 【发布时间】:2018-05-28 09:46:44 【问题描述】:

我有以下 SQL 表(在 mysql 中):

students
+-----+------------+
| id  | first_name | 
+-----+------------+
| 01  | John       |
+-----+------------+
| 02  | Jane       | 
+-----+------------+
| 03  | Peter      | 
+-----+------------+

academics
+-----+-----------+----------+------+
| id  | year_start| year_end |status|
+-----+-----------+----------+------+
| 10  | 2016      | 2017     |1     |
+-----+-----------+----------+------+
| 20  | 2017      | 2018     |0     |
+-----+-----------+----------+------+

enrollments
+----+------------+-------------+
| id | student_id | academic_id |
+----+------------+-------------+
| 1  | 01         | 10          |
+----+------------+-------------+
| 2  | 02         | 20          |
+----+------------+-------------+
| 3  | 01         | 20          |
+----+------------+-------------+

我如何从students tableenrollments table 获得当前学年未注册或enrollments table 中没有当前学年记录的学生。

现在我可以通过以下查询获取students table 中没有在enrollments table 中注册详细信息的学生:

$students = \DB::table('students')
        ->select(
            'students.id',
            'first_name'
        )
        ->leftJoin('enrollments','enrollments.student_id','=','students.id')
        ->whereNull('enrollments.student_id')
        ->get();

根据上表中的数据,此查询将返回学生Peter - 03

但是我如何才能找到没有当前学年入学详细信息的学生?

这是我确定当前学年的方式:

$current_academic = Academic::where('status', 1)->first();

使用现有查询,我如何加入academics table,以便查询出当前学年没有入学记录的学生。 非常感谢您认真的回答和建议。

【问题讨论】:

你从 $current_academic 中得到了什么? 我得到了当前学年。在这种情况下 2017/2018 的 id 是 10 【参考方案1】:
$current_academic = Academic::where('status', 1)->first();

$students = \DB::table('students')
    ->select(
        'students.id',
        'first_name'
    )
    ->whereNotExists( function ($query) use ($current_academic) 
        $query->select(DB::raw(1))
        ->from('enrollments')
        ->whereRaw('students.id = enrollments.student_id')
        ->where('enrollments.academic_id', '=', $current_academic->id);
    )
    ->get();

让我们给出一些细节:

1- whereNotExists 子句将只返回子查询中没有任何行的学生。

2- 子查询选择登记表中存在的学生,他们的 Academics_id 为 10

希望对你有帮助

【讨论】:

“他们的 id 是 10”是什么意思?招生表中没有学生 id 为 10。 我收到了Parse error: syntax error, unexpected '' 我认为是因为您添加了use ($current_academic) 。你能帮忙解决一下吗? 别打扰我已经修好了。稍后将在测试后更新您的代码,看看它是否解决了问题。 我只是忘记将 '' 替换为 '=',请查看更新后的查询 谢谢老兄让它工作了。你知道今天是我在这个查询上花费的第三天。昨天我更接近但不知道如何将参数传递给 whereNotExists 函数,因为我在文档中没有看到这样的例子。祝福上帝你今天来了。【参考方案2】:

让我们以最有说服力的方式做到这一点:

首先,您需要在 Student.php 模型文件中包含它

public function academics()

    return $this->belongsToMany('App\Academic', 'enrollments', 'student_id', 'academic_id'); 

这在你的 Academic.php 模型文件中

public function students()

    return $this->belongsToMany('App\Student', 'enrollments', 'academic_id','student_id'); 

现在你可以通过这种方式得到你想要的:

$students = \App\Student::whereDoesntHave('academics')
->orWhereHas('academics',function($q) use ($academic)
  $q->where('id',$academic->id)->count();
,'=',0)->get();

【讨论】:

哇。谁不喜欢清晰。现在看看。 不需要吗? ->get() 当然。更正。它对你有用吗?相当优雅! 我收到Parse error: syntax error, unexpected '' 在 where 语句的等号后添加了分号,现在我得到了 Can't use method return value in write context【参考方案3】:
$students = \DB::table('students')
        ->select(
            'students.id',
            'first_name'
        )
        ->leftJoin('enrollments','enrollments.student_id','=','students.id')
        ->whereNull('enrollments.student_id')
        ->orWhere('enrollments.academic_id','<>',$current_academic->id)
        ->get();

【讨论】:

这将返回学生:约翰和彼得。看看学生约翰在当前学年就读的招生表。 伙计……这就是“”的原因。你会因为 null 而得到 Peter,而 Jane 因为她没有被学者录取 10. 抱歉,我要的是 John 而不是 Jane。的确,简没有就读 10 年级,所以我应该得到彼得和简,但事实并非如此。 没有实际数据库我能做的就是这些……我不知道,我认为查询得到了您的要求。 我认为我收到 Peter、Jane 和 John 的原因是 John 有两个注册 - 过去 (2017/2018 id-20) 和当前 (2016/2017 id-10)。这样,他的 id 在登记表中重复了两次。你怎么看?

以上是关于Laravel - 从一个表中获取不存在于另一个表中的记录,并附加了 where 子句的主要内容,如果未能解决你的问题,请参考以下文章

只要它们不存在于另一个表T-SQL中,就从一个表中检索记录[重复]

从一个表中选择 Laravel 5.1 中另一个表中不存在的所有记录

php 选择值(不存在于另一个表中)

从 2 个表中获取数据,其中一个表依赖于另一个表

在一个表中查找不存在于另一个表中的ID

SQL Server 查询。用户存在于另一个表中但不存在用户的位置