使用条件语句获取相关模型的唯一计数

时间:2018-07-18 06:49:04

标签: php laravel collections eloquent laravel-5.6

我需要获得制作了某些样式的食谱,一定次数的用户的列表。

用户有食谱,食谱有制作过程。

用户可以有很多食谱,食谱可以有很多会话。

食谱具有样式,我追求的是针对特定样式进行会话的用户。不过,我追求的是唯一计数,而不是总计数。

食谱样式为'12C','21A','21B','21BA','21BB','21BC','21BD','21BE','21BF','22A'。

就我而言,我追求的是至少制作了3种不同样式的食谱的用户。因此,如果用户制作了3个食谱, “ 12C”中的2个和“ 21A”中的一个,则查询不应返回它们。但是,如果用户制作了3个食谱, “ 12C”,“ 21A”和“ 21B”各一个,则应将它们退回。

我在下面的内容中添加了一个列表,该列表列出了具有3种或以上与上述样式匹配的菜谱会话的用户列表,但这并不是这些会话的唯一计数,因此已制作3种菜谱的用户-2个'12C'和'21A'之一-不应返回时:

App\Models\User::whereHas('recipes', function ($query) {
        $query->whereIn('style_id', ['12C', '21A', '21B', '21BA', '21BB', '21BC', '21BD', '21BE', '21BF', '22A'])
            ->has('sessions');
    }, '>=', 3)
    ->get();

我需要添加什么,以允许whereHas回调仅基于style_id返回唯一记录?

或者,我是否可以使用从与上述类似的查询中检索到的集合,并遍历每个用户,并将食谱数组缩减为基于style_id的唯一食谱:

\App\Models\User::whereHas('recipes', $callback)
    ->with(['recipes' => $callback])
    ->take(5)
    ->get()
    ->transform(function ($user) {
        $user->recipes = $user->recipes->unique('style_id');
        return $user;
    });

这是我的尝试,但是此操作的结果仍然包含一系列食谱,每style_id包含多个食谱。

修改

这是我的模型定义。

用户

public function recipes()
{
    return $this->hasMany(Recipe::class);
}

食谱

public function sessions()
{
    return $this->hasMany(Session::class);
}

2 个答案:

答案 0 :(得分:0)

请尝试这个,让我知道,

      \App\Models\User::withCount([
        'recipes' => function ($query) {
            $query->whereIn('style_id', ['12C', '21A', '21B', '21BA', '21BB', '21BC', '21BD', '21BE', '21BF', '22A'])
                ->groupBy('style_id')
                ->havingRaw('COUNT(id) > ?', [2])
                ->has('sessions');
        }
    ])->get();

已编辑:向集合添加了过滤器

 \App\Models\User::withCount([
'recipes' => function ($query) {
    $query->whereIn('style_id', ['12C', '21A', '21B', '21BA', '21BB', '21BC', '21BD', '21BE', '21BF', '22A'])
        ->groupBy('style_id')
        ->havingRaw('COUNT(id) > ?', [2])
        ->has('sessions');
}
])
->get()
 ->filter(function ($user) {

    return $user->recipes_count > 2;
});

答案 1 :(得分:0)

使用修改后的withCount()

User::withCount(['recipes' => function ($query) {
    $query->select(DB::raw('COUNT(DISTINCT style_id)'))
        ->whereIn('style_id', ['12C', '21A', '21B', '21BA', '21BB', '21BC', '21BD', '21BE', '21BF', '22A'])
        ->has('sessions');
}])->having('recipes_count', '>=', 3)->get();