Как создать сгруппированную структуру на основе поля в результате запроса?

Я пытаюсь сгруппировать по годам в cakephp3. Я могу получить данные, используя следующий способ, но они не сгруппированы по годам (так, как я хочу).

$query = $this->Alerts->query();
$year = $query->func()->year([
    'added_on' => 'literal'
]);

$month = $query->func()->monthname(['added_on' => 'literal']);
$monthAlertsCount = $query->func()->count($month);
$data = $query
    ->select([
        'year' => $year,
        'month' => $month,
        'count' => $monthAlertsCount
    ])
    ->group($year)
    ->group($month);

$status = "success";
$this->set('response', $status);
$this->set('year', $data);
$this->set('_serialize', ['response','year']);

Токовый выход выглядит следующим образом:

{

    "response":"success",
    "year":[
        {
            "year":"2013",
            "month":"November",
            "count":"1"
        },
        {
            "year":"2014",
            "month":"February",
            "count":"2"
        },
        {
            "year":"2014",
            "month":"January",
            "count":"3"
        },
        {
            "year":"2015",
            "month":"December",
            "count":"6"
        },
        {
            "year":"2015",
            "month":"February",
            "count":"3"
        },
        {
            "year":"2015",
            "month":"January",
            "count":"4"
        },
        {
            "year":"2016",
            "month":"January",
            "count":"83"
        }
    ]

}

Ожидаемый результат:

{

    "response":"success",
    "year":[
        {
            "2013":[
                {
                    "month":"November",
                    "count":"1"
                }
            ],
            "2014":[
                {
                    "month":"February",
                    "count":"2"
                },
                {
                    "month":"January",
                    "count":"3"
                }
            ],
            "2015":[
                {
                    "month":"December",
                    "count":"6"
                },
                {
                    "month":"February",
                    "count":"3"
                },
                {
                    "month":"January",
                    "count":"4"
                }
            ],
            "2016":[
                {
                    "month":"January",
                    "count":"83"
                }
            ]
        }
    ]

}

Кто-нибудь может помочь мне получить ожидаемый результат в cakephp3?

1 ответ

Используйте метод сбора groupBy() - помните, запросы являются объектами коллекции (вид)!

$data = $query
    ->select([
        'year' => $year,
        'month' => $month,
        'count' => $monthAlertsCount
    ])
    ->group($year)
    ->group($month)
    ->groupBy('year');

Это создаст желаемую сгруппированную структуру, однако не удалит year поле из отдельных строк, если вы хотите удалить их, используйте маппер, как

// ...
->groupBy('year')
->map(function ($rows) {
    foreach ($rows as &$row) {
        unset($row['year']);
    }
    return $rows;
});

Смотрите также

Другие вопросы по тегам