我正在尝试从表中获取记录列表,其中PK不在复合表中。如果你看到下面的表格,我试图得到candidates
以外的所有pool
,所以在这种情况下,我应该只获得Eric
。
+-------------+ +-------------+
| candidates | | pools |
+-------------+ +-------------+
| id | name | | id | name |
+----+--------| +----+--------|
| 1 | John | | 1 | Pool A |
| 2 | Richard| | 2 | Pool B |
| 3 | Eric | | 3 | Pool C |
+----+--------+ +----+--------+
+--------------------------+
| candidate_pools |
+--------------------------+
| pool_id | candidate_id |
+---------+----------------|
| 1 | 1 |
| 1 | 2 |
| 3 | 2 |
| 2 | 1 |
+---------+----------------+
$crashedCarIds = CrashedCar::pluck('car_id')->all();
$cars = Car::whereNotIn('id', $crashedCarIds)->select(...)->get();
哪个应该有效,但是在我们相当大且快速增长的数据库中,在一个经常被很多人访问的页面上看起来效率极低。
在普通的MySQL中你会做这样的事情:
WHERE candidates.id NOT IN
( SELECT candidate_id
FROM candidate_pools
LEFT JOIN pools
ON candidate_pools.pool_id = pool.id
)
注意:这些表只是一个简单的说明,但实际的数据库设置和查询要大得多。
答案 0 :(得分:0)
我设法使用范围,如下所示:
public function scopeNotInPool($query) {
$query->whereNotIn('candidate_id', function ($query) {
$query->select('candidate_id')
->from('candidate_pool')
->join('pool', function ($join) {
$join->on('pool.id', '=', 'candidate_pool.pool_id');
}
)
;
});
return $query;
}
然后称之为:
$candidates = Models\Candidate::notInPool()->get();