Laravel - количество месяцев по месяцам - PullRequest
0 голосов
/ 20 апреля 2020

Я использую Laravel красноречивую модель для получения данных из БД. Возьмите всех пользователей с историей, зарегистрированной за последние 6 месяцев.

Результат БД:

 {
            "id": 2,
            "permissions": 3,
            "is_banned": 0,
            "datetime_last_logged": "2020-04-20 09:59:25",
            "last_login_ip": "127.0.0.1",
            "is_deleted": 0,
            "logged": [
                {
                    "id": 9,
                    "user_id": 2,
                    "datetime_logged": "2020-04-20T07:59:22.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 10,
                    "user_id": 2,
                    "datetime_logged": "2020-04-18T07:59:22.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 11,
                    "user_id": 2,
                    "datetime_logged": "2020-01-20T08:59:23.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                },
                {
                    "id": 12,
                    "user_id": 2,
                    "datetime_logged": "2020-03-20T08:59:25.000000Z",
                    "datetime_loggout": null,
                    "login_ip": "127.0.0.1"
                }
            ]

Мне нужно получить значение счетчика из моего зарегистрированного поля, например: October - 0, December - 0, January - 1, February - 0, March -1, April - 2

Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Если у вас уже есть коллекция, вы можете использовать собственный класс Laravels Collection, чтобы сгруппировать элементы по соответствующим месяцам, а затем отобразить их в сгруппированном массиве для подсчета значений:

collect($dbResult['logged'])
    ->groupBy(function ($item, $key) {
        return \Carbon\Carbon::parse($item['datetime_logged'])->month;
    })
    ->map(function ($item, $key) {
        return collect($item)->count();
    });

Возвращает коллекцию например, с номером месяца (начиная с 1) в качестве ключа и количеством вхождений в сгруппированном наборе в качестве значения:

example result

Если хотите, вы можете изменить результат операции groupBy на

return \Carbon\Carbon::parse($item['datetime_logged'])->format('F');

, чтобы он возвращал название месяца вместо номера.

example result


Мое ужасное решение для вашего требования заполнить все месяцы с шести месяцев:

$monthsInterval = \Carbon\CarbonPeriod::create(today()->subMonths(5), '1 month', today());

$placeholder = collect($monthsInterval)->mapWithKeys(function ($item, $key) {
    return [$item->format('F') => 0];
});

$userLogInsPerMonth = collect($dbResult['logged'])
    ->groupBy(function ($item, $key) {
        return \Carbon\Carbon::parse($item['datetime_logged'])->format('F');
    })
    ->map(function ($item, $key) {
        return collect($item)->count();
    });

dd($placeholder->merge($userLogInsPerMonth));

Это чудовище возвращает что-то вроде этого:

merged months example

1 голос
/ 20 апреля 2020

если вы собираетесь много работать с этими данными, я рекомендую вам создать новый столбец в вашей таблице, чтобы вам было легче фильтровать.

Вы можете получить месяц с углеродом:

$date = Carbon::parse('2020-03-20T08:59:25.000000Z')->format('F');

Вывод:

March

Также вы можете сделать foreach:

$logs= [];
foreach($users as $user){
  $date = $user->datetime_logged;
  $month = Carbon::parse($date)->format('F');
  $logs [] = $month;
}

Здесь у вас есть массив со всеми месяцами, вам нужно только считать за все месяцы:

$count = array_count_values($logs);

Выход:

Array
(
  [January] => 2
  [February] => 2
)

https://www.php.net/manual/en/function.array-count-values.php

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...