Laravel Archent는 결과를 일 단위로 그룹화합니다.
현재 테이블이 있습니다.page_views
방문자가 페이지에 접속할 때마다 1개의 행을 기록하고 사용자의 IP/ID와 페이지 자체의 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
포맷합니다.
이에 대한 해결책을 찾은 것 같습니다. 열쇠는 mysql의 DATE() 함수입니다.이 함수는 DateTime을 Date로 변환합니다.
DB::table('page_views')
->select(DB::raw('DATE(created_at) as date'), DB::raw('count(*) as views'))
->groupBy('date')
->get();
단, 이것은 원시 쿼리이기 때문에 실제로는 Laravel Archent 솔루션이 아닙니다.다음은 웅변적인 구문에서 생각해 낸 것입니다.첫 번째 where 절은 비교하기 위해 탄소 날짜를 사용합니다.
$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"')
));
카본(라벨 내장) 사용 가능
// 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
});
내가 하는 방법은 이렇다.간단한 예이지만, 내 질문을 훨씬 더 쉽게 관리할 수 있게 해줬습니다.
$visitorTraffic = PageView::where('created_at', '>=', \Carbon\Carbon::now->subMonth())
->groupBy(DB::raw('Date(created_at)'))
->orderBy('created_at', 'DESC')->get();
대부분의 데이터베이스 문제와 마찬가지로 데이터베이스를 사용하여 해결해야 합니다.
그룹화할 데이터를 저장하고 인덱스를 사용하면 효율적이고 명확한 방법으로 이 문제를 해결할 수 있습니다.
이행 작성
$table->tinyInteger('activity_year')->unsigned()->index();
$table->smallInteger('activity_day_of_year')->unsigned()->index();
모델 갱신
<?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);
}
사용.
$viewsPerDay = PageView::perDay()->get();
mysql을 사용하여 포맷된 날짜에 따라 결과를 필터링할 수 있습니다(Mysql/Mariadb 도움말에 대해서는 여기를 참조).laravel-5.4에서는 다음과 같은 것을 사용할 수 있습니다.
Model::selectRaw("COUNT(*) views, DATE_FORMAT(created_at, '%Y %m %e') date")
->groupBy('date')
->get();
저도 같은 문제가 있었어요, 저는 현재 Larabel 5.3을 사용하고 있습니다.
사용하고 있다DATE_FORMAT()
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))
이게 도움이 됐으면 좋겠네요.
PageView::select('id','title', DB::raw('DATE(created_at) as date'))
->get()
->groupBy('date');
DATETIME 대신 DATE에 따라 데이터를 그룹화하려면 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();
이것은 오래된 질문이며 여러 가지 답변이 있다는 것을 알고 있습니다.아래 라라벨에 대한 문서와 내 경험에 따르면 어떻게 일을 처리하는 것이 좋은 "완벽한 방법"인가?
모델에 이렇게 뮤테이터/게터를 추가합니다.
public function getCreatedAtTimeAttribute()
{
return $this->created_at->toDateString();
}
또 다른 방법은 모델의 컬럼을 캐스팅하고$cast
배열
$casts = [
'created_at' => 'string'
]
여기서 중요한 점은, 이 모델에서는 Carbon을 다시 사용할 수 없다는 것입니다.왜냐하면, Arctive는 항상 열을 스트링에 넣기 때문입니다.
도움이 되었으면 좋겠다:)
카본이 없는 Larabel 4.2 사용
다음은 최근 10일을 캡처하여 타임스탬프에 created_day로 각 행을 카운트하는 방법입니다.
$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>';
}
도움이 되었으면 좋겠다
이 문제는 다음과 같은 방법으로 해결할 수도 있습니다.
$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();
이 방법은 올바르게 작동하며 많은 프로젝트에서 사용했습니다. 예를 들어, 지난 30일 동안 뷰 데이터를 얻을 수 있습니다.
$viewsData = DB::table('page_views')
->where('page_id', $page->id)
->whereDate('created_at', '>=', now()->subDays(30))
->select(DB::raw('DATE(created_at) as data'), DB::raw('count(*) as views'))
->groupBy('date')
->get();
에 는, 「IP」를 할 수 .DISTINCT
같이 .
$viewsData = DB::table('page_views')
->where('page_id', $page->id)
->whereDate('created_at', '>=', now()->subDays(30))
->select(DB::raw('DATE(created_at) as data'), DB::raw('count(DISTINCT user_ip) as visitors'))
->groupBy('date')
->get();
열 이름을 조작하여 쉽게 사용자 정의할 수 있습니다.
선택 쿼리와 groupBy 메서드를 모두 해석해야 하므로 다음 코드를 사용하여 날짜별로 그룹화할 수 있습니다.
$counts = DB::table('page_views')->select(DB::raw('DATE(created_at) as created_at'), DB::raw('COUNT(*) as views'))->
groupBy(DB::raw('DATE(created_at)'))->
get();
mysql에서는 타임스탬프가 있는 MONTH 키워드를 larabel 파라미터로 추가할 수 있습니다.이렇게 할 수 있습니다.
Payement::groupBy(DB::raw('MONTH(created_at)'))->get();
통계 작성용 라라벨 패키지를 만들었습니다.https://github.com/Ifnot/statistics
웅변, 탄소, 지표에 기초하고 있기 때문에 매우 사용하기 쉽습니다.날짜 그룹화된 표시기를 추출하는 데 유용할 수 있습니다.
$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;
```
언급URL : https://stackoverflow.com/questions/20603075/laravel-eloquent-get-results-grouped-by-days
'source' 카테고리의 다른 글
VueJ + Vuex에서 여러 웹 소켓 엔드포인트를 처리하는 방법 (0) | 2022.09.24 |
---|---|
해당 함수 내에서 함수 이름을 얻는 방법은 무엇입니까? (0) | 2022.09.24 |
iframe에서 상위 URL에 액세스합니다. (0) | 2022.09.24 |
Vue router not loading component (0) | 2022.09.24 |
좌측 아우터 조인과 좌측 조인은 동일합니까? (0) | 2022.09.24 |