Laravel 加入以检索总计数
Laravel Joins to retrieve total count
我一直在尝试通过文档和多次尝试来解决这个问题,但我无法解决这个非常简单的问题。我正在使用 Laravel 7.
我有 3 个 table。
模型之间的关系设置为 Training hasMany Episodes。我的完成 table 有 user_id, episode_id 因为它是一个多对多的关系来显示用户观看了哪一集。
培训 table : id, title, description
剧集 table:id、标题、episode_number、描述、video_url、training_id (foreign_key)
完成数 table:id,user_id,episode_id
在我的索引视图中,我每次训练都会进行一次,我想显示有多少用户至少观看了 1 集。我尝试 eager-load 集 table 的培训,然后我想加入完成 table,然后我想 GROUP BY user_id 并计算它们,但它没有'根本不起作用...请帮忙? :)
我试过的代码:
$trainings = Training::with('user')->with(['episodes' => function ($query) {
$query->join('completions', 'episodes.id', '=', 'completions.episode_id')
->join('users', 'completions.user_id', '=', 'users.id')
->select('completions.*, episodes.*', DB::raw('COUNT(completions.user_id) as totalctn'))
->groupBy('completions.user_id');
}])->latest()->get();
非常感谢阅读/帮助我!
而不是
DB::raw('some query here')
试试这个:
$trainings = Training::with('user')->with(['episodes' => function ($query) {
$query->join('completions', 'episodes.id', '=', 'completions.episode_id')
->join('users', 'completions.user_id', '=', 'users.id')
->select('completions.*, episodes.*')
->groupBy('completions.user_id')
->select([DB::raw('COUNT(completions.user_id) as totalctn'),'some','column','you','need']);
}])->latest()->get();
更新 2
开始训练的用户总数(训练中有 1 集或多集)。
像这样的东西在 mysql 我想,请尝试。
$userCount = User::select(DB::raw('count(distinct(user_id))'))
->join('completions', 'completions.user_id', 'users.id')
->join('episodes', 'completions.episode_id', 'episodes.id')
->whereColumn('trainings.id', 'episodes.training_id')
->toSql(); //get the raw sql to use below
$trainings = Training::with('episodes')
->select('trainings.*',
DB::raw( "($userCount) as user_count" ) //insert above sql. take note of the parentheses, it's important since it's actually enclosing the entire sql statement from above
)
->get();
Laravel实际上在withCount
方法后面使用了类似的方法。
这里发生了什么:
->select('trainings.*',
这是一个正常的 select 要求 select 训练的所有列 table
DB::raw( "($userCount) as user_count" )
$userCount
会给我们 SQL 来计算完成 table 中出现的唯一 user_ids。此查询的最终结果将只是计数,因此我们将 subquery
作为名为 user_count
的列附加到 select 列表中。
//in case the subquery needs a basic explanation.
$userCount
查询:这里重要的条件是whereColumn
中的条件。这就是使此查询附加到正在 select 的训练 table 中的每一行的原因。所以这个查询基本上转化为:对于训练 table 中的每一行,获取所有相关的剧集并计算唯一的用户 ID。这给出了在特定培训的完成列表中至少有一集的唯一用户数。
更新
For every training, I'd like to show how many users has watched at least 1 episode.
Training::with(['episodes' => function($query){
return $query->withCount('users');
}])->get();
现在 Episode 关系将有一个名为 'users_count' 的属性,或者顺着这些词,指示观看该剧集的用户数量。
更新前
And my completions table has user_id, episode_id because it is a many
to many relation to show which episode has been watched by users.
因此,可以安全地假设您的 User 模型具有一个 belongsToMany 关系方法,该方法通过完成 table 链接 User 和 Episode。类似于此:
public function completedEpisodes(){
return $this->belongsToMany(Episode::class, 'completions_table');
}
I'd like to show how many users has watched at least 1 episode.
现在,您可以计算至少有一个 completedEpisode
的所有用户,如下所示:
User::has('completedEpisode')->count(); //use get() instead of count if you want to retrieve the results
我一直在尝试通过文档和多次尝试来解决这个问题,但我无法解决这个非常简单的问题。我正在使用 Laravel 7.
我有 3 个 table。
模型之间的关系设置为 Training hasMany Episodes。我的完成 table 有 user_id, episode_id 因为它是一个多对多的关系来显示用户观看了哪一集。
培训 table : id, title, description
剧集 table:id、标题、episode_number、描述、video_url、training_id (foreign_key)
完成数 table:id,user_id,episode_id
在我的索引视图中,我每次训练都会进行一次,我想显示有多少用户至少观看了 1 集。我尝试 eager-load 集 table 的培训,然后我想加入完成 table,然后我想 GROUP BY user_id 并计算它们,但它没有'根本不起作用...请帮忙? :)
我试过的代码:
$trainings = Training::with('user')->with(['episodes' => function ($query) {
$query->join('completions', 'episodes.id', '=', 'completions.episode_id')
->join('users', 'completions.user_id', '=', 'users.id')
->select('completions.*, episodes.*', DB::raw('COUNT(completions.user_id) as totalctn'))
->groupBy('completions.user_id');
}])->latest()->get();
非常感谢阅读/帮助我!
而不是
DB::raw('some query here')
试试这个:
$trainings = Training::with('user')->with(['episodes' => function ($query) {
$query->join('completions', 'episodes.id', '=', 'completions.episode_id')
->join('users', 'completions.user_id', '=', 'users.id')
->select('completions.*, episodes.*')
->groupBy('completions.user_id')
->select([DB::raw('COUNT(completions.user_id) as totalctn'),'some','column','you','need']);
}])->latest()->get();
更新 2
开始训练的用户总数(训练中有 1 集或多集)。 像这样的东西在 mysql 我想,请尝试。
$userCount = User::select(DB::raw('count(distinct(user_id))'))
->join('completions', 'completions.user_id', 'users.id')
->join('episodes', 'completions.episode_id', 'episodes.id')
->whereColumn('trainings.id', 'episodes.training_id')
->toSql(); //get the raw sql to use below
$trainings = Training::with('episodes')
->select('trainings.*',
DB::raw( "($userCount) as user_count" ) //insert above sql. take note of the parentheses, it's important since it's actually enclosing the entire sql statement from above
)
->get();
Laravel实际上在withCount
方法后面使用了类似的方法。
这里发生了什么:
->select('trainings.*',
这是一个正常的 select 要求 select 训练的所有列 tableDB::raw( "($userCount) as user_count" )
$userCount
会给我们 SQL 来计算完成 table 中出现的唯一 user_ids。此查询的最终结果将只是计数,因此我们将subquery
作为名为user_count
的列附加到 select 列表中。//in case the subquery needs a basic explanation.
$userCount
查询:这里重要的条件是whereColumn
中的条件。这就是使此查询附加到正在 select 的训练 table 中的每一行的原因。所以这个查询基本上转化为:对于训练 table 中的每一行,获取所有相关的剧集并计算唯一的用户 ID。这给出了在特定培训的完成列表中至少有一集的唯一用户数。
更新
For every training, I'd like to show how many users has watched at least 1 episode.
Training::with(['episodes' => function($query){
return $query->withCount('users');
}])->get();
现在 Episode 关系将有一个名为 'users_count' 的属性,或者顺着这些词,指示观看该剧集的用户数量。
更新前
And my completions table has user_id, episode_id because it is a many to many relation to show which episode has been watched by users.
因此,可以安全地假设您的 User 模型具有一个 belongsToMany 关系方法,该方法通过完成 table 链接 User 和 Episode。类似于此:
public function completedEpisodes(){
return $this->belongsToMany(Episode::class, 'completions_table');
}
I'd like to show how many users has watched at least 1 episode.
现在,您可以计算至少有一个 completedEpisode
的所有用户,如下所示:
User::has('completedEpisode')->count(); //use get() instead of count if you want to retrieve the results