Laravel - получить данные по месяцам и суммировать их (varchar) - PullRequest
0 голосов
/ 27 декабря 2018

Я видел похожие вопросы, но, честно говоря, я не видел ничего, что могло бы привести меня в правильное русло, и это потому, что я также ищу лучший способ сделать это.

В определенный момент в моем приложении я использую chartjs, где мне нужно показать месяцы, а затем значения (продажи).Для этого я знаю (или я думаю), что мне нужно извлечь данные сгруппировать по месяцам , и я дошел до этого момента:

$records = TabelaAngariacao::select('preco', 'created_at')
    ->where('estado', '=', 'Vendido')
    ->get()
    ->groupBy(function($date) {
       return Carbon::parse($date->created_at)->format('m');
    });

Ну ... как вы видите, яЯ не SUMING ничего, и это потому, что в моей базе данных мои значения хранятся в varchar (с точками!), И я знаю, что это не правильный способ делать вещи, но вэта точка меняет все, для меня это сейчас не решение, так как же мне изменить эту функцию, чтобы удалить точки и получить правильную сумму ?Я пытался использовать CAST, но он дает мне неопределенную функцию.

Есть предложения?Спасибо за ваше время, привет.

- РЕДАКТИРОВАТЬ -

Привет всем, я думаю, что я почти у цели, я не знал о функции преобразования ,там я могу внести некоторые изменения в поле preco (price), в котором все еще остается проблема varchar, поэтому мне нужно удалить точки для того, чтобы сумма работала, что у меня есть:

$records = TabelaAngariacao::select('preco', 'created_at')
            ->where('estado', '=', 'Vendido')
            ->get()
            ->groupBy(function($date) {
                return Carbon::parse($date->created_at)->format('m');
            })->transform(function ($value) { //it can also be map()
                $nStr = str_replace(".", "", $value->pluck('preco'));
                return [
                    'preco_sum' => $nStr->sum()
                ];
            });

но это не работает, потому что $ nStr это строка ... что мне нужно сделать?если я конвертирую в float, то сумма не будет работать ... если я уйду с этого пути, сумма между 175.000 и 1.000.000 будет 176.000, что неправильно ... какие-либо мысли?

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Я делаю это для суммирования и группировки по месяцам

$ventas = Operacion::select([
            DB::raw("DATE_FORMAT(created_at, '%Y') year"),
            DB::raw("DATE_FORMAT(created_at, '%m') month"),
            DB::raw("SUM(1) cantidad"),
            DB::raw("SUM(operacion_total) total"),
            DB::raw("SUM(CASE WHEN estado = 'OPEFIN' THEN operacion_total ELSE 0 END) total_finalizado")
        ])->groupBy('year')->groupBy('month')->get();

И если вам нужно разыграть некоторый varchar, вы можете сделать

CAST(operacion_total as DECIMAL(9,2))

, чтобы столбец в select мог быть

DB::raw("SUM(CAST(operacion_total as DECIMAL(9,2))) total"),

Пожалуйста, попробуйте это и дайте мне знать, как это работает :)

0 голосов
/ 27 декабря 2018

Друг, если вы хотите использовать коллекцию для группировки, а также суммировать значения в группе, я считаю, что еще не слишком поздно.

Давайте воспользуемся примером ниже:

Я будусделайте пример результата вашего красноречивого запроса следующим образом: скажем, у нас есть пользователи

    $users = collect();
    foreach (range(1, 9) as $item) {
        foreach (range(1, 9) as $ninja) {
            $users->push([
                'created_at' => \carbon('2018-0' . $item),
                'preco' => (string)'160.00' . $item
            ]);
        }
    }

Выше должно быть что-то вроде этого ...

[
  {
    "created_at": "2018-01-01 00:00:00",
    "preco": "160.001"
  },
  {
    "created_at": "2018-01-01 00:00:00",
    "preco": "160.001"
  },
  {
    "created_at": "2018-01-01 00:00:00",
    "preco": "160.001"
  },
...
]

Затем мы группируем пои преобразовать (или отобразить) результат, используя ...

   $users->map(function ($user) {
        $user['preco'] = str_replace('.', '', $user['preco']);
        return $user;
    })->groupBy(function ($user) {  
        return Carbon::parse($user['created_at'])->format('m');
    })->transform(function ($value, $key) { //it can also be map()
        return [
            'preco_sum' => $value->pluck('preco')->sum()
        ];
    });

Здесь мы имеем сумму каждой группы месяцев ...

ОБНОВЛЕНИЕ

Если запись большая, то вы можете сократить пинг map, используя Accessor

У вас может быть что-то, что форматирует ваше поле preco следующим образомв вашей модели, например, так:

/**
 * Get the user's first name.
 *
 * @param  string  $value
 * @return string
 */
public function getPrecoAttribute($value)
{
    return str_replace('.', '', $value);
}

Это означает, что когда Laravel строит объекты Eloquent, это значение будет отформатировано, как указано, что означает, что вы можете удалить первый map() из результата.

PS: вам может понадобиться мутатор, чтобы изменить его на формат, который вы хотите в базе данныхпри сохранении.

Ура!

0 голосов
/ 27 декабря 2018

Попробуйте этот запрос.

$records = TabelaAngariacao::select(
   \DB::raw('sum(cast(preco as double precision)) as sums'), 
   \DB::raw("DATE_FORMAT(created_at,'%M %Y') as months"))
->where('estado', '=', 'Vendido')
->groupby('months')->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...