Laravel Eloquent uzyskuje wyniki pogrupowane według dni


Obecnie mam tabelę odsłon, która rejestruje jeden wiersz dla każdego dostępu użytkownika do strony, rejestrując ip/id użytkownika i identyfikator samej strony. Muszę dodać, że kolumna created_at jest typu: timestamp, czyli zawiera godziny/minuty/sekundy. Kiedy próbuję wykonać zapytanie groupBy, nie grupuje tych samych dni ze względu na różnicę w sekundach.
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
... ... ...

Chciałbym uzyskać wyniki na podstawie wyświetleń/dzień, aby uzyskać coś takiego:
date views
==== =====
10-11-2013 15
10-12 2013 45
... ...

Myślę, że będę musiał zagłębić się w zapytania DB :: raw (), aby to osiągnąć, ale wszelkie zrozumienie bardzo by pomogło, dzięki
Edycja: Dodano wyjaśnienie do formatu created_at.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Uważam, że znalazłem rozwiązanie tego problemu, kluczem jest funkcja DATE () w mysql, która konwertuje DateTime na samą datę:
DB::table('page_views')
->select(DB::raw('DATE(created_at) as date'), DB::raw('count(*) as views'))
->groupBy('date')
->get();

Jednak nie jest to tak naprawdę rozwiązanie Laravel Eloquent, ponieważ jest to surowe żądanie. Oto, co wymyśliłem w składni elokwentnej. Pierwsza klauzula where wykorzystuje do porównania daty emisji dwutlenku węgla.
$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"')
));
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć węgla (zintegrowany w 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
});
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Tak to robię. Krótki przykład, ale moje zapytanie stało się znacznie łatwiejsze w zarządzaniu
$visitorTraffic = PageView::where('created_at', '>=', \Carbon\Carbon::now->subMonth())
->groupBy(DB::raw('Date(created_at)'))
->orderBy('created_at', 'DESC')->get();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz filtrować wyniki na podstawie sformatowanej daty za pomocą mysql (

zobacz pomoc tutaj
https://mariadb.com/kb/en/library/date_format/
Mysql/Mariadb) i użyj czegoś takiego w laravel-5.4:
Model::selectRaw("COUNT(*) views, DATE_FORMAT(created_at, '%Y %m %e') date")
->groupBy('date')
->get();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Miałem ten sam problem, obecnie używam Laravel 5.3.
Używam
DATE_FORMAT ()
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))

Mam nadzieję, że to ci pomoże.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

PageView::select('id','title', DB::raw('DATE(created_at) as date'))
->get()
->groupBy('date');
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podobnie jak większość problemów z bazami danych, należy je rozwiązać za pomocą bazy danych.
Przechowując dane, które chcesz zgrupować i używając indeksów, możesz uzyskać wydajną i prostą metodę rozwiązania tego problemu.

Utwórz migrację
>
$table->tinyInteger('activity_year')->unsigned()->index();
$table->smallInteger('activity_day_of_year')->unsigned()->index();


Aktualizacja modelu
>
<?phpnamespace App\Models; use DB;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model; class PageView extends Model
{
public function scopePerDay($query){ $query->groupBy('activity_year');
$query->groupBy('activity_day_of_year'); return $query; } public function setUpdatedAt($value)
{
$date = Carbon::now(); $this->activity_year = (int)$date->format('y');
$this->activity_day_of_year = $date->dayOfYear; return parent::setUpdatedAt($value);
}


Za pomocą
>
$viewsPerDay = PageView::perDay()->get();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć funkcji CAST, aby pogrupować dane według DATY zamiast DATETIME.
$visitorTraffic = PageView::select('id', 'title', 'created_at')
->get()
->groupBy(DB::raw('CAST(created_at AS DATE)'));
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ostrzeżenie: niezweryfikowany kod.
$dailyData = DB::table('page_views')
->select('created_at', DB::raw('count(*) as views'))
->groupBy('created_at')
->get();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wiem, że to stare pytanie i istnieje wiele odpowiedzi. W każdym razie, zgodnie z poniższymi dokumentami i moim doświadczeniem laravel, jest to dobry „elokwentny sposób” radzenia sobie ze sprawami
W swoim modelu dodaj mutator/Getter w ten sposób
public function getCreatedAtTimeAttribute()
{
return $this->created_at->toDateString();
}

Innym sposobem jest odlewanie kolumn
w swoim modelu wypełnij tablicę
$ cast
$casts = [
'created_at' => 'string'
]

Haczyk polega na tym, że nie będziesz w stanie ponownie użyć węgla w tym modelu, ponieważ Eloquent zawsze będzie rzucać kolumnę do rzędu
Mam nadzieję że to pomoże :)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używanie Laravel 4.2 bez węgla
W ten sposób pobieram ostatnie dziesięć dni i liczę każdy wiersz z tym samym znacznikiem czasu created_at.
$q = Spins::orderBy('created_at', 'desc')
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))
->take(10)
->get(array( DB::raw('Date(created_at) as date'),
DB::raw('COUNT(*) as "views"')
));
foreach ($q as $day) { echo $day->date. " Views: " . $day->views.'';}

Mam nadzieję że to pomoże
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

w mysql możesz dodać słowo kluczowe MONTH z parametrem
timestamp w laravel możesz to zrobić w ten sposób
Payement::groupBy(DB::raw('MONTH(created_at)'))->get();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zbudowałem pakiet laravel do generowania statystyk:

https://github.com/Ifnot/statistics
https://github.com/Ifnot/statistics
Oparty jest na elokwencji, węglu i wskaźnikach, dzięki czemu jest bardzo łatwy w użyciu. Może być przydatne do pobierania wskaźników pogrupowanych według daty.
$statistics = Statistics::of(MyModel::query());$statistics->date('validated_at');$statistics->interval(Interval::$DAILY, Carbon::createFromFormat('Y-m-d', '2016-01-01'), Carbon::now())$statistics->indicator('total', function($row) {
return $row->counter;
});$data = $statistics->make();echo $data['2016-01-01']->total;

```
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz również rozwiązać ten problem w następujący sposób:
$totalView = View::select(DB::raw('Date(read_at) as date'), DB::raw('count(*) as Views'))
->groupBy(DB::raw('Date(read_at)'))
->orderBy(DB::raw('Date(read_at)'))
->get();

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się