加入Laravel的Eloquent

时间:2018-03-08 12:27:45

标签: database laravel select join eloquent

我有一个访问模型,我得到了我想要的数据:

$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

2 个答案:

答案 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。