php - wheredate - Laravel Eloquent obtiene resultados agrupados por días
wheredate laravel (13)
Advertencia: código no probado.
$dailyData = DB::table(''page_views'')
->select(''created_at'', DB::raw(''count(*) as views''))
->groupBy(''created_at'')
->get();
Actualmente tengo una tabla de page_views que registra una fila por cada vez que un visitante accede a una página, registrando la ip / id del usuario y el id de la página misma. Debo añadir que la columna created_at es del tipo: timestamp, por lo que incluye las horas / minutos / segundos. Cuando intento hacer consultas groupBy, no se agrupan los mismos días juntos debido a la diferencia de segundos.
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
... ... ...
Me gustaría obtener resultados basados en vistas / día, así puedo obtener algo como:
date views
==== =====
10-11-2013 15
10-12 2013 45
... ...
Estoy pensando que tendré que profundizar en las consultas de DB :: raw () para lograr esto, pero cualquier idea me sería de gran ayuda, gracias.
Editar: Se agregó una aclaración del formato created_at.
Al igual que la mayoría de los problemas de la base de datos, deben resolverse utilizando la base de datos.
Al almacenar los datos que desea agrupar y usar índices, puede lograr un método eficiente y claro para resolver este problema.
Crea la migración
$table->tinyInteger(''activity_year'')->unsigned()->index();
$table->smallInteger(''activity_day_of_year'')->unsigned()->index();
Actualizar el modelo
<?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);
}
Uso
$viewsPerDay = PageView::perDay()->get();
Así es como lo hago. Un pequeño ejemplo, pero hace que mi consulta sea mucho más manejable
$visitorTraffic = PageView::where(''created_at'', ''>='', /Carbon/Carbon::now->subMonth())
->groupBy(DB::raw(''Date(created_at)''))
->orderBy(''created_at'', ''DESC'')->get();
Creé un paquete laravel para hacer estadísticas: https://github.com/Ifnot/statistics
Se basa en elocuencia, carbono e indicadores, por lo que es realmente fácil de usar. Puede ser útil para extraer indicadores agrupados por fecha.
$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;
`` `
Creo que he encontrado una solución a esto, la clave es la función DATE () en mysql, que convierte un DateTime en Just Date:
DB::table(''page_views'')
->select(DB::raw(''DATE(created_at) as date''), DB::raw(''count(*) as views''))
->groupBy(''date'')
->get();
Sin embargo, esto no es realmente una solución Laravel Eloquent, ya que esta es una consulta en bruto. Lo siguiente es lo que se me ocurrió en la sintaxis Eloquent-ish. La cláusula first where usa fechas de carbono para comparar.
$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"'')
));
Estoy resolviendo un problema de esta manera.
$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();
Para agrupar datos de acuerdo con DATE en lugar de DATETIME, puede usar la función CAST.
$visitorTraffic = PageView::select(''id'', ''title'', ''created_at'')
->get()
->groupBy(DB::raw(''CAST(created_at AS DATE)''));
Puede filtrar los resultados en función de la fecha formateada utilizando mysql ( consulte aquí la ayuda de Mysql / Mariadb ) y use algo como esto en laravel-5.4:
Model::selectRaw("COUNT(*) views, DATE_FORMAT(created_at, ''%Y %m %e'') date")->groupBy(''date'')->get();
Puedes usar Carbon (integrado en 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
});
Sé que esta es una pregunta VIEJA y hay respuestas múltiples. Sin embargo, de acuerdo con los documentos y mi experiencia en laravel a continuación es la buena "manera elocuente" de manejar las cosas
En su modelo, agregue un mutador / Getter como este
public function getCreatedAtTimeAttribute()
{
return $this->created_at->toDateString();
}
Otra forma es lanzar las columnas en su modelo, rellenar la matriz $cast
$casts = [
''created_at'' => ''string''
]
El truco aquí es que no podrá usar el carbono en este modelo nuevamente ya que Eloquent siempre convertirá la columna en una cadena
Espero eso ayude :)
Tuve el mismo problema, actualmente estoy usando Laravel 5.3.
Yo uso DATE_FORMAT()
->groupBy(DB::raw("DATE_FORMAT(created_at, ''%Y-%m-%d'')"))
Espero que esto te ayude.
Usando Laravel 4.2 sin Carbono
Así es como tomé los últimos diez días y cuento cada fila con el mismo día created_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>'';
}
Espero que esto ayude
en mysql puede agregar la palabra clave MONTH con la marca de tiempo como parámetro en laravel, puede hacerlo así
Payement::groupBy(DB::raw(''MONTH(created_at)''))->get();