【问题标题】:How to calculate the total amount for similar keys in PHP using Laravel eloquent/collections如何使用 Laravel eloquent/collections 计算 PHP 中相似键的总量
【发布时间】:2019-12-23 20:51:24
【问题描述】:

我目前有 API 返回的以下 json 响应。我可以使用 Laravel Eloquent 将其退回。有几个用户,每个用户都有几张收据。收据具有类型和状态。我想尝试获取与其类型和状态相关的每张收据的总金额。我能够使用

返回以下 json 响应
$this->user->with('receipts')->has('receipts')->get(['id', 'name']);

我尝试过使用多种 laravel 集合方法https://laravel.com/docs/5.8/collections#available-methods 但我仍然无法得到想要的响应。

    {
        "id": 1,
        "name": "kent",
        "receipts": [
            {
                "id": 1,
                "user_id": 1,
                "type_id": 1,
                "status": 0,
                "amount": 100
            },
            {
                "id": 2,
                "user_id": 1,
                "type_id": 1,
                "status": 0,
                "amount": 100
            },
            {
                "id": 3,
                "user_id": 1,
                "type_id": 2,
                "status": 1,
                "amount": 50
            },
            {
                "id": 4,
                "user_id": 1,
                "type_id": 2,
                "status": 0,
                "amount": 30
            },
            {
                "id": 5,
                "user_id": 1,
                "type_id": 2,
                "status": 0,
                "amount": 30
            },
            {
                "id": 6,
                "user_id": 1,
                "type_id": 1,
                "status": 0,
                "amount": 20
            },
            {
                "id": 7,
                "user_id": 1,
                "type_id": 1,
                "status": 1,
                "amount": 10
            }
        ]
        },
        {
            "id": 2,
            "name": "allison",
            "receipts": [
                {
                    "id": 9,
                    "user_id": 2,
                    "type_id": 1,
                    "status": 0,
                    "amount": 20
                }
        ]
    }
]

我希望得到以下内容

    {
        "id": 1,
        "name": "kent",
        "receipts": [
            {
                "performance and deleted": 220,
                "performance and not deleted": 10,
                "project and deleted": 60,
                "project and deleted": 50
            }
        ]
    },
    {
        "id": 2,
        "name": "allison",
        "receipts": [
            {
                "performance and deleted": 20,
                "performance and not deleted": 0,
                "project and deleted": 0,
                "project and not deleted": 0
            }
        ]
    }
]

【问题讨论】:

    标签: php laravel laravel-5 eloquent


    【解决方案1】:

    您可以使用 foreach 和其他循环来制作您想要的 json! 使用此函数将您的集合转换为您想要的 json:

    public function convert(Collection $collection) 
    {
        $result_collection = $collection;
        $payment_collections = [];
        foreach ($result_collection->receipts as $receipt)
        {
            $payment["type_id${receipt->type_id} and status${$receipt->status}"] = $receipt->amount;
        }
        $result_collection->receipts = $payment_collections;
        return $result_collection;
    }
    
    

    这与获取总金额的方法相同。只需放置一个 foreach 并将每个数量添加到初始化为 0 的变量中;

    还有其他方法,例如在您的资源集合中更改 toArray 函数。

    【讨论】:

    • 我得到的属性 [receipts] 在此集合实例上不存在。
    【解决方案2】:

    你应该能够得到金额的总和

    $this->user->with(['receipts' => function($query) {
        $query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
    }])->has('receipts')->get(['id', 'name']);
    

    您可以使用收集方法来获得所需的输出

    $this->user->with(['receipts' => function($query) {
        $query->selectRaw("SUM(amount) as amount, type_id, status, user_id")->groupBy('type_id', 'status', 'user_id');
    }])->has('receipts')->get(['id', 'name'])
    ->each(function ($user) {
        $user->setRelation(
            'receipts',
            $user->receipts->mapWithKeys(function ($receipt) {
                return [
                    $receipt->type_id . ' and ' . $receipt->status => $receipt->amount // format the key as you wish
                ];
            })
        );
    })
    

    【讨论】:

    • 我试过了,这就是我得到的,一个空的收据数组[ { "id": 1, "name": "kent", "receipts": [] }, { "id": 2, "name": "allison", "receipts": [] } ]
    • @CEJ 查看更新后的答案。还需要将外键添加到 select 语句中。
    • 我怎样才能像预期的答案一样填充它?这确实对类型和状态进行了分组
    • 你的意思是你需要像type_id1 and status0这样的键
    • 是的,我需要像 admin status": 220 user status": 10 superadmin status":60 这样的密钥
    【解决方案3】:

    我编写脚本时假设您的数据是一个 PHP 数组,因此您可以更改我的代码的某些部分。 例如你可以改变:

    $row['receipts']
    // To 
    $row->receipts
    

    不管怎样

    // The function in your controller
    function index(){
      $users=User::whereHas('receipts')->with('receipts')->get()->toArray();
      return convert($users);
    }
    // The helper function 
    function convert($data){
      $data=collect($data);
    $allTypes=[];
    $allStatuses=[];
    return $data->each(function($row) use (&$allTypes,&$allStatuses){
        $types=collect($row['receipts'])->pluck('type_id')->toArray();
        $statuses=collect($row['receipts'])->pluck('status')->toArray();
        $allTypes=array_unique(array_merge($allTypes,$types));
        $allStatuses=array_unique(array_merge($allStatuses,$statuses));
    })->map(function ($row,$index) use (&$allTypes,&$allStatuses){
        $result=[];
        $receipts=collect($row['receipts']);
        foreach ($allTypes as $type){
            foreach ($allStatuses as $status){
                $result["type_id {$type} and status {$status}: "]=$receipts->where('type_id',$type)->where('status',$status)->sum('amount');
            }
        }
        $row['receipts']=$result;
        return $row;
    });
    }
    

    【讨论】:

    • 阅读我写的内容,您可能会更改代码的某些部分,我对其进行了测试,效果非常好,我上传了结果的屏幕截图
    • 或者,如果您不想更改我的代码,您可以使用 ->get()->toArray(); 将 DB 结果解析为数组;然后将其传递给我编写的函数。
    • 我编辑了代码并向您展示了如何获取您的用户,先检查一遍
    • 感谢您的编辑。有没有办法只使用收集方法而不是 foreach 循环。让它更简单
    • 请检查更新后的预期答案。这就是我所期望的
    猜你喜欢
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2021-06-13
    • 2021-01-19
    • 2011-05-27
    • 1970-01-01
    相关资源
    最近更新 更多