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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27636858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:35:24  来源:igfitidea点击:

How to injecting custom columns in Laravel query builder

phplaravelquery-builder

提问by OwlPaste

I got a query with many joins, wheres, ect. And what I need to do is insert some maths into each result set as it will be feeding either a csv export or be displayed on page. Can later on even be sent back as API, so what I really want to do is prepare the data once, and then use it where ever.

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

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

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

So the question is, can I somehow iterate through my results and do some maths as I get them? Like maybe a callback on each result?

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

For example get difference between some values retrieved in each row, or add in additional row signifying pass/fail. Basically I was wondering if there was a better way of doing things then later on doing a foreach() on the results to go through them, do the maths and add in additional columns, thereby destroying the pagination support and having to convert the result into an ugly array?

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

回答by lukasgeiter

I can think of three methods. For example, let's say you want to get the difference between the columns cand e.

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

Select with raw expressions

使用原始表达式选择

With raw expressions you can use all available SQL functions and ordinary math operators as well. Basically you can do everything what you could in a normal SQL select because Laravel will insert the string directly into the query.

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

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

Now the result will have a differenceCEproperty containing the result of the division.

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

Attribute accessors

属性访问器

This only works with Eloquent Models!

这仅适用于 Eloquent 模型!

You can create a new dynamic attribute in your model, that will be calculated the moment you access it

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

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

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

Access the property:

访问属性:

$mymodel->difference;

for(each)

对于(每个)

You can also use a simple loop like:

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

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

Or if you're using Eloquent there's the eachmethod you can call on a collection

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

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

Just be aware that method 1 and 2 may result in (slightly) better performance. SQL just because it has to go through every record anyways and the method with the attribute accessor has the advantage that it will be lazy loaded. Meaning the calculation only happens when you use it (when you access the property)

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