【问题标题】:Laravel Eloquent - Where In AllLaravel Eloquent - 在哪里
【发布时间】:2015-04-22 09:24:52
【问题描述】:

Laravel 4.2 中,我试图实现一个返回所有用户的查询,这些用户具有所有特定的活动。到目前为止,我有一个查询,它返回所有具有许多活动之一的用户:

//$selectedActivities being an array
        $userByActivities = User::with('activities')
                ->whereHas('activities', function($query) use($selectedActivities){
                    $query->whereIn('id', $selectedActivities);
                })->get();

更清楚一点:给定活动a,b,c。我正在寻找所有有活动 a AND b AND c 的用户。我的查询返回所有有活动a OR b OR c的用户。

感谢您的帮助。

编辑:

lukasgeiter 提供的解决方案导致以下查询:

select * from `users` where 
        (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '7') >= 1 
        and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '3') >= 1 
        and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '1') >= 1 
        and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '2') >= 1

Jarek Tkaczyk提供的解决方案:

$userByActivities = User::with('activities')
 ->whereHas('activities', function($query) use($selectedActivities) {
     $query->selectRaw('count(distinct id)')->whereIn('id', $selectedActivities);
 }, '=', count($selectedActivities))->get();

对于类似的请求,会产生以下查询:

select * from `users` where (select count(distinct id) from `activities` 
    inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` 
    where `activity_user`.`user_id` = `users`.`id` and `id` in ('7', '3', '1', '2')) = 4

【问题讨论】:

  • Jarek Tkaczyk 提出的解决方案比公认的优化得多

标签: laravel eloquent


【解决方案1】:

您必须为此添加多个 whereHas

$query = User::with('activities');
foreach($selectedActivities as $activityId){
    $query->whereHas('activities', function($q) use ($activityId){
        $q->where('id', $activityId);
    });
}
$userByActivities = $query->get();

【讨论】:

  • 这似乎是合乎逻辑的,既然你这么说。非常感谢您的帮助。
  • 对于未知数量的相关项目来说,这太过分了。您应该将计数调整为 count(distinct id) 并使 whereHas 查找数组中的确切项目数。
  • @JarekTkaczyk 怎么做?
【解决方案2】:

如果你得到Cardinality violation: 1241 Operand should contain 2 column(s),问题是嵌套的selectCount 添加到正常的select count(*) 而不是覆盖现有的选择,所以更改为$query->distinct()->whereIn('id', $selectedActivities); 对我有用,或者更改为$query->select(DB::raw(count(distinct id)))

【讨论】:

  • $query->distinct()->whereIn('id', $selectedActivities); 为我工作,谢谢
猜你喜欢
  • 2017-05-07
  • 2018-02-07
  • 2014-12-13
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多