Laravel Eloquent получает результаты, сгруппированные по дням

В настоящее время у меня есть таблица page_views, которая записывает одну строку для каждого посещения посетителем страницы, записи ip / id пользователя и идентификатора самой страницы. Я должен добавить, что столбец created_at имеет тип: timestamp, поэтому он включает часы / минуты / секунды. Когда я пытаюсь выполнить запросы GroupBy, он не группирует те же дни вместе из-за разницы в секундах.

created_at page_id user_id ========== ======= ======= 10-11-2013 3 1 10-12 2013 5 5 10-13 2013 5 2 10-13 2013 3 4 ... ... ... 

Я хотел бы получить результаты на основе просмотров / дня, поэтому я могу получить что-то вроде:

  date views ==== ===== 10-11-2013 15 10-12 2013 45 ... ... 

Я думаю, что мне нужно копать в DB :: raw () запросы, чтобы достичь этого, но любое понимание поможет очень, спасибо

Изменить: добавлено уточнение формата created_at.

Вы можете использовать Carbon (интегрированный в Laravel)

 // Carbon use Carbon\Carbon; $visitorTraffic = PageView::select('id', 'title', 'created_at') ->get() ->groupBy(function($date) { return Carbon::parse($date->created_at)->format('Y'); // grouping by years //return Carbon::parse($date->created_at)->format('m'); // grouping by months }); 

Я считаю, что нашел решение для этого, ключ – это функция DATE () в mysql, которая преобразует DateTime в просто Date:

 DB::table('page_views') ->select(DB::raw('DATE(created_at) as date'), DB::raw('count(*) as views')) ->groupBy('date') ->get(); 

Однако это не действительно решение Laravel Eloquent, так как это сырой запрос. Следующее – это то, что я придумал в синтаксисе Eloquent-ish. Первый, где предложение использует даты углерода для сравнения.

 $visitorTraffic = PageView::where('created_at', '>=', \Carbon\Carbon::now->subMonth()) ->groupBy('date') ->orderBy('date', 'DESC') ->get(array( DB::raw('Date(created_at) as date'), DB::raw('COUNT(*) as "views"') )); 

Вот как я это делаю. Короткий пример, но сделал мой запрос намного более управляемым

 $visitorTraffic = PageView::where('created_at', '>=', \Carbon\Carbon::now->subMonth()) ->groupBy(DB::raw('Date(created_at)')) ->orderBy('created_at', 'DESC')->get(); 

Чтобы группировать данные в соответствии с DATE вместо DATETIME, вы можете использовать функцию CAST.

 $visitorTraffic = PageView::select('id', 'title', 'created_at') ->get() ->groupBy(DB::raw('CAST(created_at AS DATE)')); 

Предупреждение: непроверенный код.

 $dailyData = DB::table('page_views') ->select('created_at', DB::raw('count(*) as views')) ->groupBy('created_at') ->get(); 

У меня была такая же проблема, в настоящее время я использую Laravel 5.3.

Я использую DATE_FORMAT()

 ->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')")) 

Надеюсь, это поможет вам.

в mysql вы можете добавить ключевое слово MONTH с меткой времени в качестве параметра в laravel, вы можете сделать это так

 Payement::groupBy(DB::raw('MONTH(created_at)'))->get(); 

Я создал пакет laravel для создания статистики: https://github.com/Ifnot/statistics

Он основан на красноречивых, углеродных и индикаторах, поэтому он очень прост в использовании. Это может быть полезно для извлечения индикаторов сгруппированных по дате.

 $statistics = Statistics::of(MyModel::query()); $statistics->date('validated_at'); $statistics->interval(Interval::$DAILY, Carbon::createFromFormat('Ym-d', '2016-01-01'), Carbon::now()) $statistics->indicator('total', function($row) { return $row->counter; }); $data = $statistics->make(); echo $data['2016-01-01']->total; 

“ `

Я знаю, что это вопрос OLD, и есть несколько ответов. Как бы то ни было, согласно документам и моему опыту на laravel ниже, это хороший «Красноречивый способ» обработки вещей

В вашей модели добавьте мутатор / Getter, как это

 public function getCreatedAtTimeAttribute() { return $this->created_at->toDateString(); } 

Другим способом является создание столбцов в вашей модели, заполнение массива $cast

 $casts = [ 'created_at' => 'string' ] 

Улов здесь заключается в том, что вы больше не сможете использовать Carbon на этой модели, так как Eloquent всегда будет отличать колонку в строку

Надеюсь, поможет 🙂