问题描述
我一直在尝试通过文档和多次尝试来弄清楚,但是我无法解决这个非常简单的问题。我正在使用Laravel 7。
我有3张桌子。
模型之间的关系设置为“训练hasMany情节”。我的完成表具有user_id,episoce_id,因为它与显示用户观看了哪个情节有很多关系。
培训表格:ID,标题,说明
片段表:ID,标题,剧集编号,描述,视频网址,training_id(外键)
补全表:id,user_id,epase_id
在索引视图中,我会讲授每一次培训,并且我想显示有多少用户观看了至少1集。我试图急于加载培训的情节表,然后我想加入完成表,然后我要对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();
非常感谢您的阅读/帮助我!
解决方法
更新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.*',
,这是正常选择,要求选择训练表的所有列 -
DB::raw( "($userCount) as user_count" )
$userCount
将为我们提供SQL来计算完成表中显示的唯一user_id的数量。该查询的最终结果将只是计数,因此我们将subquery
作为名为user_count
的列附加到选择列表中。//in case the subquery needs a basic explanation.
-
$userCount
查询:此处的重要条件是whereColumn
中的条件。这就是使此查询附加到所选培训表中的每一行的原因。因此,该查询的基本含义是:对于Trainings表中的每一行,获取所有相关情节并计算唯一的用户ID。这样一来,就不会有在特定训练的完成列表中至少有一集的唯一身份用户。
更新
对于每次培训,我想显示有多少用户观看了至少1集。
Training::with(['episodes' => function($query){
return $query->withCount('users');
}])->get();
现在,情节关系将具有一个名为“ users_count”的属性,或带有这些词的属性,它指示观看该情节的用户数量。
更新前
我的完成表有user_id,episod_id,因为它很多 可以显示用户观看了哪一集。
因此,可以安全地假设您的用户模型具有一个通过完成表链接用户和情节的belongsToMany关系方法。与此类似:
public function completedEpisodes(){
return $this->belongsToMany(Episode::class,'completions_table');
}
我想显示有多少用户观看了至少1集。
现在,您可以像这样计算所有至少有一个completedEpisode
的用户:
User::has('completedEpisode')->count(); //use get() instead of count if you want to retrieve the results
,
代替
DB::raw('some query here')
尝试一下:
$trainings = Training::with('user')->with(['episodes' => function ($query) {
$query->join('completions','episodes.id','=','completions.episode_id')
->join('users','users.id')
->select('completions.*,episodes.*')
->groupBy('completions.user_id')
->select([DB::raw('COUNT(completions.user_id) as totalctn'),'some','column','you','need']);
}])->latest()->get();