在Laravel语句中使用多个联接会覆盖值

时间:2019-03-16 14:36:16

标签: php mysql laravel join eloquent

我正在尝试创建一个Laravel语句,该语句应为每个用户返回正确的值,以表示答案和问题的数量,例如:

$users = User::join('user_answers', 'users.id', '=', 'users_answers.user_id')
        ->join('user_questions', 'users.id', '=', 'user_questions.user_id')
        ->select(
            'users.id',
            'users.username',
            DB::raw('COUNT(user_answers.user_id) AS answers'),
            DB::raw('COUNT(user_questions.user_id) AS questions')
        )
        ->groupBy('users.id');

注意:必须使用groupBy,因为它在DataTables中使用,否则它将仅显示一行。

当我尝试:

dd($users->first());

这是我得到的:

Example

如您所见,由于某些原因,这些值对于问题和答案都是相同的,并且是不正确的。我想联接有某种重叠。

例如,如果我删除其中一个联接,而只保留其中一列,数字将正确显示,如下所示:

Example 2

老实说,我在这里很迷路,不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:3)

我很久没有使用 Eloquent 了,所以我不知道是否有一种“雄辩”的方式可以对单个查询执行此操作。但是在SQL中,我会在SELECT子句中使用相关的子查询:

$users = User::select(
            'users.id',
            'users.username',
            DB::raw('(
                SELECT COUNT(*)
                FROM user_answers
                WHERE users_answers.user_id = users.id
            ) AS answers'),
            DB::raw('(
                SELECT COUNT(*)
                FROM user_questions
                WHERE user_questions.user_id = users.id
            ) AS questions'),
        );

答案 1 :(得分:3)

我将使用Eloquent's relational methods来构造它。您甚至可以使用withCount() method来构建查询。

关系方法将类似于:

public function answers()
{
    return $this->hasMany(\App\Answer::class);
}

数据透视表命名要记住的一件事是Laravel expects the tables to be named alphabetically。因此,对于一个many-to-many relationship,它会期望将枢轴命名为answer_user。但是,您可以在模型的关系方法中定义自定义数据透视表名称。

一旦在模型中设置了关系方法,就应该能够构建类似于以下内容的查询:

User::withCount(['answers', 'questions'])->get();

一旦获得成功,就可以使用select语句进行约束。