如何在 Laravel 查询构建器中注入自定义列

Owl*_*ste 2 php query-builder laravel

我得到了一个有很多连接的查询,在哪里,等等。我需要做的是在每个结果集中插入一些数学运算,因为它将提供 csv 导出或显示在页面上。以后甚至可以作为API发回,所以我真正想做的是准备一次数据,然后在任何地方使用它。

$result = DB::table('a')
->join('b')
->where('c')
->orderBy('d')
->select('e');

if ($paginate) {
    $query->paginate();
} else {
    $query->get();
}
Run Code Online (Sandbox Code Playgroud)

所以问题是,我能否以某种方式迭代我的结果并在得到它们时做一些数学运算?就像每个结果的回调一样?

例如,获取每行中检索到的某些值之间的差异,或添加表示通过/失败的附加行。基本上我想知道是否有更好的做事方式,然后在结果上执行 foreach() 以通过它们,进行数学运算并添加额外的列,从而破坏分页支持并且不得不将结果转换为一个丑陋的数组?

luk*_*ter 5

我能想到三种方法。例如,假设您想获取列c和之间的差异e

使用原始表达式选择

通过原始表达式,您还可以使用所有可用的 SQL 函数和普通的数学运算符。基本上你可以在普通的 SQL 选择中做任何你能做的事情,因为 Laravel 会直接将字符串插入到查询中。

$result = DB::table('a')
    ->join('b')
    ->where('c')
    ->orderBy('d')
    ->select('e', DB::raw('c - e AS differenceCE'));
Run Code Online (Sandbox Code Playgroud)

现在结果将有一个differenceCE包含除法结果的属性。

属性访问器

这仅适用于 Eloquent 模型!

您可以在模型中创建一个新的动态属性,该属性将在您访问它时进行计算

class MyModel extends Eloquent {
    protected $appends = array('difference');

    public function getDifferenceAttribute(){
        return $this->attributes['c'] - $this->attributes['e'];
    }
}
Run Code Online (Sandbox Code Playgroud)

访问属性:

$mymodel->difference;
Run Code Online (Sandbox Code Playgroud)

对于(每个)

您还可以使用一个简单的循环,如:

foreach($result as $model){
    // do math
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您正在使用 Eloquent,则each可以在集合上调用该方法

$result->each(function($model){
    // do math
});
Run Code Online (Sandbox Code Playgroud)

请注意,方法 1 和 2 可能会导致(稍微)更好的性能。SQL 只是因为它无论如何都必须遍历每条记录,并且带有属性访问器的方法具有延迟加载的优点。这意味着计算仅在您使用它时发生(当您访问该属性时)