0

I am trying to group by Year in cakephp3. I am able to get data using following way, but it's not still grouped by year(The way I want.)

$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']);

Current output is as follows:

{

    "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"
        }
    ]

}

Expected Output:

{

    "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"
                }
            ]
        }
    ]

}

Can anybody help me get the expected output in cakephp3?

ndm
  • 59,784
  • 9
  • 71
  • 110

1 Answers1

0

Use the collection method groupBy() - remember, queries are collection objects (kind of)!

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

That will create the desired grouped structure, however it won't remove the year field from the individual rows, if you want them removed, use a mapper, like

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

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • Hii, Thanks for your reply, it almost close to what i wanted, but I am not still able to remove year ->groupBy('year') ->map(function ($row) { unset($row['year']); return $row; }); does not remove year from the output – Akshay Malhotra Jan 13 '16 at 17:20
  • @AkshayMalhotra Forgot that the mapper doesn't traverse into the groups... check the updated code example. – ndm Jan 13 '16 at 18:52