我有两个表 - 联系人和访问:
联系方式表
id | name
----- | -------
1 | Joe
2 | Sally
参观表
id | contact_id | pathname | referrer
----- | ------- | ------- | -------
1 | 1 | about | google
2 | 1 | pricing | null
3 | 1 | signup | null
4 | 2 | about | null
5 | 2 | signup | null
使用雄辩,我想检索所有具有 pathname = 'signup' 和 referrer = 'google' 的 contacts。
到目前为止我所得到的是:
Contact::whereHas('visits', function($query) {
$query->where('pathname','=','signup');
})
->orWhereHas('visits', function($query) {
$query->where('referrer','=','google');
})
->get();
它可以正确检索访问过定价或注册页面的所有联系人。
但是,此示例还会检索 Sally(来自上面的示例表),因为她访问了注册,但未被 google 引用。我需要一种方法来只检索Joe,他是由谷歌推荐并访问过定价的。
有什么想法吗?预先感谢!
您可以使用:
Contact::whereHas('visits', function($query) {
$query->where('pathname','=','signup');
})
->whereHas('visits', function($query) {
$query->where('referrer','=','google');
})
->get();
上述代码的精炼版本:
Contact::whereHas('visits', function($query) {
$query->where('pathname','signup')->where('referrer','google');
})->get();
几个值得注意的点:
where()
子句。=
,因此您可以省略它。whereHas()
子句。Первый ответ с двумя 其中 дважды делает 加入 к одной 和 той же таблице, что не очень хорошо。 Второй ответ не будет работать поскольку на участке
$query->where('pathname','signup')->where('referrer','google');
каждая строка таблицы 访问 будет проверяться на соответствие обоим условиям,но каждая из них по отдельности не соответствует двум условиям。
Вам необходимо использовать подход с подсчетом на соответствие общему количеству условий:
$total_number_of_conditions = 2; // общее количество условий where
Contact::whereExists(function (Builder $b) use (int $total_number_of_conditions) {
$b->selectRaw('COUNT(*) as count')
->from('visits')
->whereColumn('сontacts.id', 'сontact_id')
->where('pathname', 'signup')->where('referrer', 'google'))
->having('count', $total_number_of_conditions);
})->get();