我有一个访问模型,我得到了我想要的数据:
$app_visits = Visit::select([
'start',
'end',
'machine_name'
])->where('user_id', $chosen_id)->get();
但我想为每次访问添加积分。每次访问都有互动(但是没有visit_id(因为其他系统我无法添加)。
最后一位开发人员就这样离开了:
$interactions = Interaction::where([
'machine_name' => $app_visit->machine_name,
])->whereBetween('date', [$app_visit->start, $app_visit->end])->get();
$points = 0;
foreach ($interactions as $interaction) {
$points += (int)$interaction->app_stage;
}
$app_visits[$key]['points'] = $points
但我真的不喜欢它,因为它很慢而且很乱。我想添加点数'总和到第一个查询,只触摸一次数据库。
@edit,因为有人要求提供数据库结构:
访问:
|id | start | end | machine_name | user_id
inteaction:
|id | time | machine_name | points
答案 0 :(得分:1)
你可以在雄辩中使用一些东西。对于这种情况,可能最有用的是select(DB::raw(sql...))
,因为您必须添加一些原始sql来检索计数。
例如:
return $query
->join(...)
->where(...)
->select(DB::raw(
COUNT(DISTINCT res.id) AS count'
))
->groupBy(...);
如果做不到这一点,我只需用原始sql替换eloquent。我们必须这么做,因为我们的数据集庞大,雄辩的模型构建已经证明有点慢。
添加结构后, 更新。为什么不根据machine_name
(甚至使用计算点的原始sql的自定义方法)添加与Interaction的关系,并使用:Visits::with('interaction.visitPoints')->...blah
?
答案 1 :(得分:0)
看一下DB而不是Eloquent: https://laravel.com/docs/5.6/queries
用于更复杂和有效的查询。 还可以在此外观中使用原始SQL。