webentwicklung-frage-antwort-db.com.de

Laravel Eloquent Ergebnisse werden nach Tagen gruppiert

Ich habe derzeit eine Tabelle mit page_views, die eine Zeile für jeden Zugriff eines Besuchers auf eine Seite aufzeichnet, wobei die IP/ID des Benutzers und die ID der Seite selbst aufgezeichnet werden. Ich sollte hinzufügen, dass die erzeugte_at-Spalte vom Typ: Zeitstempel ist, also die Stunden/Minuten/Sekunden enthält. Wenn ich groupBy-Abfragen versuche, werden aufgrund des Sekundenunterschieds nicht dieselben Tage gruppiert.

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
  ...                ...          ...

Ich möchte Ergebnisse basierend auf Ansichten/Tag erhalten, damit ich Folgendes erhalten kann:

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

Ich denke, ich muss in DB :: raw () - Abfragen recherchieren, um dies zu erreichen, aber jede Einsicht würde sehr helfen, danke

Bearbeiten: Erläuterung des Formats "create_at" hinzugefügt.

30
jct

Ich glaube, ich habe eine Lösung dafür gefunden. Der Schlüssel ist die DATE () - Funktion in mysql, die eine DateTime in nur Date konvertiert:

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

Dies ist jedoch nicht wirklich eine Lösung von Laravel Eloquent, da dies eine reine Abfrage ist. Das Folgende ist, was ich in der Eloquent-ish-Syntax gefunden habe. Die erste Klausel where verwendet Kohlenstoffdaten zum Vergleich.

$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"')
                            ));
41
jct

Sie können Carbon verwenden (in Laravel integriert) 

// 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
    });
39
dede

So mache ich es. Ein kurzes Beispiel, aber meine Abfrage wurde viel übersichtlicher

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

Wie die meisten Datenbankprobleme sollten sie mit der Datenbank gelöst werden.

Durch Speichern der zu gruppierenden Daten und durch Verwendung von Indizes können Sie eine effiziente und eindeutige Methode zur Lösung dieses Problems erreichen.

Erstellen Sie die Migration

    $table->tinyInteger('activity_year')->unsigned()->index();
    $table->smallInteger('activity_day_of_year')->unsigned()->index();

Aktualisieren Sie das Modell

<?php

namespace 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);
 }

Verwendungszweck

   $viewsPerDay = PageView::perDay()->get();
3
henryallsuch

Ich hatte das gleiche Problem, ich verwende derzeit Laravel 5.3.

Ich benutze DATE_FORMAT()

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

Hoffentlich hilft dir das.

3
Haidren Amalia

Sie können die Ergebnisse basierend auf dem formatierten Datum mithilfe von mysql filtern ( Siehe hier für Mysql/Mariadb-Hilfe ) und verwenden Sie Folgendes in laravel-5.4:

Model::selectRaw("COUNT(*) views, DATE_FORMAT(created_at, '%Y %m %e') date")->groupBy('date')->get();
3
ako

Um Daten nach DATE anstelle von DATETIME zu gruppieren, können Sie die CAST-Funktion verwenden.

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

Warnung: ungeprüfter Code.

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

Laravel 4.2 ohne Kohlenstoff verwenden

So greife ich mir die letzten zehn Tage an und zähle jede Zeile mit dem gleichen Tag create_at timestamp.

$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.'<br>';

}

Hoffe das hilft

1
btaylor507
PageView::select('id','title', DB::raw('DATE(created_at) as date'))
          ->get()
          ->groupBy('date');
1
Shanu Singh

in mysql können Sie das MONTH-Schlüsselwort hinzufügen, das den Zeitstempel als Parameter hat. In Laravel können Sie es so machen

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

Ich habe ein Laravel-Paket für die Erstellung von Statistiken erstellt: https://github.com/Ifnot/statistics

Es basiert auf Eloquent, Kohlenstoff und Indikatoren und ist daher sehr einfach zu bedienen. Es kann nützlich sein, Datumsgruppenkennzeichen zu extrahieren.

$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;

`` `

0
Ifnot

Ich weiß, das ist eine ALTE Frage und es gibt mehrere Antworten. Laut den Unterlagen und meiner Erfahrung auf Laravel ist der gute "eloquente Weg" im Umgang mit den Dingen

Fügen Sie in Ihrem Modell einen solchen Mutator/Getter hinzu

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

Eine andere Möglichkeit besteht darin, die Spalten in Ihrem Modell umzuwandeln und das $cast-Array aufzufüllen

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

Der Haken dabei ist, dass Sie den Carbon bei diesem Modell nicht mehr verwenden können, da Eloquent die Säule immer in eine Saite gießen wird

Ich hoffe es hilft :)

0
Sithira

Ich löse das Problem auf diese Weise. 

$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();
0
Rubel Ahmed