定制 alexmg86/laravel-sub-query 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

alexmg86/laravel-sub-query

Composer 安装命令:

composer require alexmg86/laravel-sub-query

包简介

Laravel subquery

README 文档

README

Social Card of Laravel Sub Query

Laravel Sub Query

PHP Composer Total Downloads Latest Stable Version License

Why is this package needed?

With standard use of Laravel, if you want the sum or find the maximum column value in the related model, you will have two database queries. What if you need to get a list of one hundred records? With this methods, it all turns into one query to the database and there is no need to load extra data.

I've also added methods for sorting by related model, or when you only need to get one latest or oldest related model for each model without multiple queries. And there is a lot more to speed up your development and code readability.

I often use this in my work and I hope it will be useful to you!

Changelog

Please see CHANGELOG for more information what has changed recently.

Say thank you

If you liked this package, please give me a star.

Installation

Install via composer

composer require alexmg86/laravel-sub-query

Use LaravelSubQueryTrait trait in your model.

use Alexmg86\LaravelSubQuery\Traits\LaravelSubQueryTrait;
use Illuminate\Database\Eloquent\Model;

class Invoice extends Model
{
    use LaravelSubQueryTrait;

Usage

If you want to get results from a relationship without actually loading them and by one request to the database you may use the these methods, which will place a new columns on your resulting models. For example:

$invoices = Invoice::withSum('items:price')
    ->withMin('items:price')
    ->withMax('items:price')
    ->withAvg('items:price')
    ->get();

echo $invoices[0]->items_price_sum;
echo $invoices[0]->items_price_min;
echo $invoices[0]->items_price_max;
echo $invoices[0]->items_price_avg;

The resulting value can be casting through the third parameter. Some types for example: date, datetime, time, char, signed, unsigned, binary.

$invoices = Invoice::withSum('items:price:signed')->get();

The following methods apply to all methods!!!

You may add the sum for multiple relations as well as add constraints to the queries:

use Illuminate\Database\Eloquent\Builder;

$invoices = Invoice::withSum(['items:price', 'goods:price,price2' => function (Builder $query) {
    $query->where('price','>',6);
}])->get();

echo $invoices[0]->items_price_sum;
echo $invoices[0]->goods_price_sum;
echo $invoices[0]->goods_price2_sum;

You may also alias the relationship sum result, allowing multiple sums on the same relationship:

use Illuminate\Database\Eloquent\Builder;

$invoices = Invoice::withSum(['items:price', 'goods:price as sum_goods_price' => function (Builder $query) {
    $query->where('price','!=',1);
}])->get();

echo $invoices[0]->items_price_sum;
echo $invoices[0]->sum_goods_price;

If you're combining withSum with a select statement, ensure that you call withSum after the select method:

$invoices = Invoice::select(['id'])->withSum('items:price')->get();

echo $invoices[0]->id;
echo $invoices[0]->items_price_sum;

In addition, using the loadSum method, you may load a relationship sum columns after the parent model has already been retrieved:

$invoice = Invoice::first();
$invoice->loadSum('items:price');

If you need to set additional query constraints on the eager loading query, you may pass an array keyed by the relationships you wish to load. The array values should be Closure instances which receive the query builder instance:

$invoice = Invoice::first();
$invoice->loadSum(['items:price' => function ($query) {
    $query->where('price', '>', 5);
}]);

And of course it is all compatible with scopes in models.

Sorting

If you want to sort by field in a related model, simply use the following method:

$invoices = Invoice::orderByRelation('items:price')->get();

or with conditions

$invoices = Invoice::orderByRelation(['items:price' => function (Builder $query) {
    $query->where('price', '>', 6);
}, 'desc', 'max'])->get();

By default, sorting is by max and desc, you can choose one of the options max, min, sum, avg, desc, acs.

$invoices = Invoice::orderByRelation('items:price', 'asc', 'sum')->get();

Working with columns

To add or multiply the required columns use this method:

$items = Item::withMath(['invoice_id', 'price'])->get();
echo $items[0]->sum_invoice_id_price;

Columns will be summed by default, you can choose one of the options +, -, *, / and set a new name.

$items = Item::withMath(['invoice_id', 'price', 'price2'], '*', 'new_column')->get();
echo $items[0]->new_column;

Working with dates

A more convenient way to select by dates. By default, sorting is by created_at.

$invoices = Invoice::whereCurrentYear('column_name')->get();
$invoices = Invoice::whereCurrentMonth()->get();
$invoices = Invoice::whereCurrentDay()->get();

Load latest or oldest relation

Imagine you want to get a list of 50 accounts, each with 100 items. By default, you will get 5000 positions and select the first ones for each account. PHP smokes nervously on the sidelines.
Wow! Now you can load only one latest or oldest related model:

$invoices = Invoice::all();
$invoices->loadOneLatest('items');
$invoices->loadOneOldest('items');

or with conditions

$invoices->loadOneLatest(['items' => function ($query) {
    $query->orderBy('id', 'desc')->where('price', '<', 6);
}]);

You can use this with relation types hasMany, belongsToMany and hasManyThrough.

Limit relations

If you want to load related model with limit, simply use the following method:

$invoices = Invoice::all();
$invoices->loadLimit('items:1');

or with conditions

$invoices->loadLimit(['items:2', 'goods:1' => function ($query) {
    $query->orderBy('id', 'desc')->where('price', '<', 6);
}]);

Note that first you write the name of the relation, and then the number of rows.

Caching

For convenience, you can now cache the received data.

// Get a the first user's posts and remember them for a day.
Invoice::withSum('items:price')->remember(now()->addDay())->posts()->get();

// You can also pass the number of seconds if you like
// (before Laravel 5.8 this will be interpreted as minutes).
Invoice::withSum('items:price')->remember(60 * 60 * 24)->get();

A more detailed description is here

Sugar

I got tired of writing some things in detail and I decided to remove them in methods.
You can see it here

alexmg86/laravel-sub-query 适用场景与选型建议

alexmg86/laravel-sub-query 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 40.15k 次下载、GitHub Stars 达 75, 最近一次更新时间为 2020 年 04 月 24 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「php」 「query」 「laravel」 「sub」 「withSum」 「withMax」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 alexmg86/laravel-sub-query 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 alexmg86/laravel-sub-query 我们能提供哪些服务?
定制开发 / 二次开发

基于 alexmg86/laravel-sub-query 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 40.15k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 75
  • 点击次数: 14
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 75
  • Watchers: 3
  • Forks: 5
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-04-24