示例:
表用户
ID | Username | sex
1 | Tony | m
2 | Andy | m
3 | Lucy | f
表分数
ID | user_id | score
1 | 2 | 4
2 | 1 | 3
3 | 1 | 4
4 | 2 | 3
5 | 1 | 1
6 | 3 | 3
7 | 3 | 2
8 | 2 | 3
预期结果:
ID | Username | sex | score_sum (sum) (desc)
2 | Andy | m | 10
1 | Tony | m | 8
3 | Lucy | f | 5
到目前为止我使用的代码:
用户模型:
class User extends Authenticatable
{
...
public function scores()
{
return $this->hasMany('App\Score');
}
...
}
分数模型
class Job extends Model
{
//i put nothing here
}
控制器中的代码:
$users = User::all();
foreach ($users as $user){
$user->score_sum = $user->scores()->sum('score');
}
$users = collect($users)->sortByDesc('score_sum');
return view('homepage', [
'users' => $users->values()->all()
]);
希望我上面的例子有意义。我的代码确实有效,但我认为必须有一种雄辩而优雅的方式来做到这一点而没有foreach
?
答案 0 :(得分:1)
以雄辩的方式执行此操作有两个选项。
选项1
第一种方法是将score_sum
添加为查询users
模型时始终包含的属性。如果您在查询score_sum
表时大部分时间都使用users
,那么这只是个好主意。如果您只需要非常具体的视图上的score_sum
或特定的业务逻辑,那么我将使用下面的第二个选项。
要执行此操作,您需要将该属性添加到users
模型,您可以在此处查看文档:{{3}}
以下是您的用例示例:
<强> /app/User.php 强>
class User extends Model
{
.
.
.
public function getScoreSumAttribute($value)
{
return $this->scores()->sum('score');
}
}
选项2
如果您只想针对单个用例执行此操作,那么最简单的解决方案就是在您将使用的最终sum()
循环中使用foreach
函数(最有可能在视图中) )。
例如在视图中:
@foreach($users as $user)
<div>Username: {{$user->username}}</div>
<div>Sex: {{$user->sex}}</div>
<div>Score Sum: {{$user->scores()->sum('price')}}</div>
@endforeach
此外,如果您不想在foreach
循环中执行此操作,则可以在Controller中的Eloquent调用中使用原始查询获取`score_sum&#39;。以下是如何做到这一点的示例:
$users = User::select('score_sum',DB::raw(SUM(score) FROM 'scores'))->get();
我没有快速的环境来测试它,你可能需要DB::raw
查询中的WHERE子句
希望这有帮助!
答案 1 :(得分:1)
这很好:
User::selectRaw('*, (SELECT SUM(score) FROM scores WHERE user_id = users.id) as score_sum')
->orderBy('score_sum', 'DESC')
->get();