Laravel Eloquent 查询同一个 table 中的兄弟姐妹并预先加载
Laravel Eloquent query siblings in same table with eager loading
我有一个名为 patients
的父 table,它与一个名为 notes
的子 table 具有一对多关系。 (即一位患者可以有多个笔记)。如果给出注释,我想为同一患者找到其他注释。注释通过名为 patient_id
.
的 fk 与患者相关
在 SQL 中,我会这样做:
SELECT * FROM notes WHERE patient_id={note.patient_id} AND id <> {note.id}
在 Eloquent 中,我有这个:
class Note extends Model
{
public function otherEncounterNotes()
{
return $this->hasMany('App\Note', 'patient_id', 'patient_id')->where('id', '<>',$this->id);
}
...
在我的数据库中,id=1 的患者有两个 id 为 1 和 2 的笔记,所以如果我查找笔记 id 1 的兄弟姐妹,我应该得到笔记 id 2。
当我使用 find()
时,它按预期工作,但是当我使用 where()
时,它 returns 原始音符而不是同级音符。有什么想法吗?
>>> Note::find(1)->otherEncounterNotes->pluck('id')
=> Illuminate\Support\Collection {#5542
all: [
2,
],
}
>>> Note::where('id',1)->with('otherEncounterNotes')->pluck('id')
=> Illuminate\Support\Collection {#5526
all: [
1,
],
}
给定一个 Note
id,你可以通过使用与 Patient
模型的关系来获得你想要的结果。
$note_id = 1;
// "Pretty" syntax, but it's 3 queries
$sibling_notes = Note::find($note_id) // Query 1
->patient // Query 2
->notes()->where('id', '<>', $note_id)->pluck('id'); // Query 3
或者使用子查询
$note_id = 1;
// A bit messier, 1 query + 1 subquery
$sibling_notes = Note::where('id', '<>', $note_id)
->where('patient_id', function ($subquery) use ($note_id) {
$subquery->select('patient_id')->from('notes')->where('id', $note_id)->limit(1);
})
->pluck('id');
// PHP >= 7.4
Note::where('id', '<>', $note_id)
->where('patient_id', fn($q) => $q->select('patient_id')->from('notes')->where('id', $note_id)->limit(1))
->pluck('id');
以后可以变成查询作用域
# Note model
public function scopeSiblingsOf($query, $note_id)
{
return $query->where('id', '<>', $note_id)
->where('patient_id', function ($subquery) use ($note_id) {
$subquery->select('patient_id')
->from('notes')
->where('id', $note_id)
->limit(1);
});
}
# Usage
Note::siblingsOf(1)->pluck('id');
我有一个名为 patients
的父 table,它与一个名为 notes
的子 table 具有一对多关系。 (即一位患者可以有多个笔记)。如果给出注释,我想为同一患者找到其他注释。注释通过名为 patient_id
.
在 SQL 中,我会这样做:
SELECT * FROM notes WHERE patient_id={note.patient_id} AND id <> {note.id}
在 Eloquent 中,我有这个:
class Note extends Model
{
public function otherEncounterNotes()
{
return $this->hasMany('App\Note', 'patient_id', 'patient_id')->where('id', '<>',$this->id);
}
...
在我的数据库中,id=1 的患者有两个 id 为 1 和 2 的笔记,所以如果我查找笔记 id 1 的兄弟姐妹,我应该得到笔记 id 2。
当我使用 find()
时,它按预期工作,但是当我使用 where()
时,它 returns 原始音符而不是同级音符。有什么想法吗?
>>> Note::find(1)->otherEncounterNotes->pluck('id')
=> Illuminate\Support\Collection {#5542
all: [
2,
],
}
>>> Note::where('id',1)->with('otherEncounterNotes')->pluck('id')
=> Illuminate\Support\Collection {#5526
all: [
1,
],
}
给定一个 Note
id,你可以通过使用与 Patient
模型的关系来获得你想要的结果。
$note_id = 1;
// "Pretty" syntax, but it's 3 queries
$sibling_notes = Note::find($note_id) // Query 1
->patient // Query 2
->notes()->where('id', '<>', $note_id)->pluck('id'); // Query 3
或者使用子查询
$note_id = 1;
// A bit messier, 1 query + 1 subquery
$sibling_notes = Note::where('id', '<>', $note_id)
->where('patient_id', function ($subquery) use ($note_id) {
$subquery->select('patient_id')->from('notes')->where('id', $note_id)->limit(1);
})
->pluck('id');
// PHP >= 7.4
Note::where('id', '<>', $note_id)
->where('patient_id', fn($q) => $q->select('patient_id')->from('notes')->where('id', $note_id)->limit(1))
->pluck('id');
以后可以变成查询作用域
# Note model
public function scopeSiblingsOf($query, $note_id)
{
return $query->where('id', '<>', $note_id)
->where('patient_id', function ($subquery) use ($note_id) {
$subquery->select('patient_id')
->from('notes')
->where('id', $note_id)
->limit(1);
});
}
# Usage
Note::siblingsOf(1)->pluck('id');