首页 > 解决方案 > Laravel Eloquent 关系与来自两个模型的属性分组

问题描述

我有两个模型InvoiceHeaderInvoiceDetail. InvoiceHeader具有以下属性(除其他外):idpos_id和。InvoiceDetail具有以下属性(除其他外):、、、。两个模型之间存在一对多的关系。pos_descriptiondateidinvoice_header_idpctprice

我想分组bypos_iddatefrom 。有了这个,我想得到价格的总和。InvoiceHeaderpctInvoiceDetail

根据我的发现,不可能同时按两个模型进行分组,因为 Eloquent 没有进行实际连接。所以我想我可以pctInvoiceDetail. 我做这样的事情:

$invoices = \App\InvoiceHeader::with(['details' => function ($query) {
        $query->select('pct')
            ->selectRaw('SUM(price) AS price')
            ->groupBy(['invoice_header_id', 'pct']);
    }])
    ->whereBetween('date', ['2018-01-01', '2018-07-31'])
    ->select(['pos_id', 'pos_description', 'date'])
    ->get();

正是在这里,我被困住了。我需要按pos_idpos_descriptiononInvoiceHeader和 group by pcton分组InvoiceDetail

从这里开始,我要走一条路线,我认为这不是最好/最简单的路线。我有一个与其InvoiceDetail集合相关的InvoiceHeader的 Eloquent集合。我觉得我应该做这个,但是因为我不知道如何将它转换为 Laravel 集合。因为它是唯一一个让我更接近我所得到的东西,所以我想我可以继续下去。但是,如果有人有更好的建议,请分享。在那之前,这就是我得到的。

我从 Eloquent 集合中制作了一个 Laravel 集合:

$collection = collect();
foreach ($invoices as $invoice) {
    foreach ($invoice->details as $detail) {
        $collection->push([
            'pos_id' => $invoice->pos_id,
            'pos_description' => $invoice->pos_description,
            'date' => $invoice->date,
            'pct' => $detail->pct,
            'price' => $detail->price,
        ]);
    }
}

这让我想到了类似的东西

$collection = [
    [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-02-28',
        'pct'             => 6,
        'price'           => 68.94
    ], [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-02-28',
        'pct'             => 21,
        'price'           => 99.99
    ], [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-02-28',
        'pct'             => 21,
        'price'           => 82.64
    ], [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-03-31',
        'pct'             => 21,
        'price'           => 431.45
    ]
]

这是我想要到达的地方,或者类似的地方:

$newCollection = [
    [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-02-28',
        'details'     => [
            [
               'pct'   => 6,
               'price' => 68.94
            ], [
               'pct'   => 21,
               'price' => 182.63
            ]
        ]
    ], [
        'pos_id'          => 1,
        'pos_description' => 'Somewhere',
        'date'            => '2018-03-31',
        'details'     => [
            [
               'pct'   => 21,
               'price' => 431.45
            ]
        ]
    ]
]

我尝试了laravel 文档中的许多功能,在集合中使用each, groupBy, map。也从这个链接的某个地方。但我似乎无法得到我想要完成的事情。我觉得我错过了一些简单的步骤,这让我做的事情太难了。

免责声明:大部分代码都松散地基于工作代码。为了简化事情,我简化了一些事情。

标签: phplaravellaravel-5laravel-5.6

解决方案


像这样的基本迭代怎么样:

$dirtyColl = [];
foreach ($collection as $key => $value) {
    $dirtyColl[$value['date']]['pos_id'] = $value['pos_id'];
    $dirtyColl[$value['date']]['pos_description'] = $value['pos_description'];
    $dirtyColl[$value['date']]['date'] = $value['date'];
    $dirtyColl[$value['date']]['details'][$value['pct']]['pct'] = $value['pct'];
    $dirtyColl[$value['date']]['details'][$value['pct']]['price'] += $value['price'];
}

print_r(array_values($dirtyColl));

结果是

Array
(
    [0] => Array
        (
            [pos_id] => 1
            [pos_description] => Somewhere
            [date] => 2018-02-28
            [details] => Array
                (
                    [6] => Array
                        (
                            [pct] => 6
                            [price] => 68.94
                        )

                    [21] => Array
                        (
                            [pct] => 21
                            [price] => 182.63
                        )

                )

        )

    [1] => Array
        (
            [pos_id] => 1
            [pos_description] => Somewhere
            [date] => 2018-03-31
            [details] => Array
                (
                    [21] => Array
                        (
                            [pct] => 21
                            [price] => 431.45
                        )

                )

        )

)

也许只是再次使用 array_values 作为“详细信息”。


推荐阅读