如何在Laravel查询生成器中注入自定义列

时间:2014-12-24 12:19:26

标签: php laravel query-builder

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

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

if ($paginate) {
    $query->paginate();
} else {
    $query->get();
}

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

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

1 个答案:

答案 0 :(得分:3)

我可以想到三种方法。例如,假设您希望获得列ce之间的差异。

选择原始表达式

使用原始表达式,您还可以使用所有可用的SQL函数和普通的数学运算符。基本上,您可以在正常的SQL选择中执行所有操作,因为Laravel会将字符串直接插入查询中。

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

现在结果将包含differenceCE属性,其中包含除法的结果。

属性访问者

这仅适用于Eloquent Models!

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

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

    public function getDifferenceAttribute(){
        return $this->attributes['c'] - $this->attributes['e'];
    }
}

访问该媒体资源:

$mymodel->difference;

对于(每)

您还可以使用简单的循环:

foreach($result as $model){
    // do math
}

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

$result->each(function($model){
    // do math
});

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