laravel - Laravel year, sum, count, group by eloquent 查询
问题描述
有人可以告诉我如何用 eloquent 构建这个查询,或者这需要用 DB:Raw 查询编写,还是最好是一个原始的 sql 查询?
select `pay_week`,
year(`start_timestamp`) as year,
sum(`total_duration`) as 'duration',
count(`pay_week`) as 'entries'
from `time_clock`
group by year(`start_timestamp`),`pay_week`;
任何有助于更好理解的帮助将不胜感激。
谢谢你。
$entries = TimeClock::select(
'pay_week',
DB::raw('count(pay_week) as entries'),
DB::raw('YEAR(start_timestamp) as year'),
DB::raw('sum(total_duration) as duration')
)
->where('user_id', $user->record_id)
->sum('total_duration')
->groupBy('pay_week')
->get();
结果是
Call to a member function groupBy() on float
我现在拥有的;
刀;
<table class="table table-hover dataTable table-striped width-full" data-plugin="dataTable">
<thead>
<th>Pay Week</th>
<th>Date Range</th>
<th>Year</th>
<th>Total Hours</th>
<th>Gross Pay</th>
<th>Entries</th>
<th>Action</th>
</thead>
<tbody>
@foreach($entries as $group)
@foreach($group->entries as $entry)
@php
$week_start = (new DateTime())->setISODate(date("Y"),$entry->pay_week)->format("m/d");
$start = \Carbon\Carbon::createFromFormat("m/d", $week_start);
$end = $start->copy()->endOfWeek()->format('m/d');
$year = \Carbon\Carbon::parse($entry->start_timestamp)->format('Y');
@endphp
<tr>
<td>{{ $entry->pay_week }}</td>
<td>{{ $start->format('m/d') . ' - ' . $end }}</td>
<td>{{ $year }}</td>
<td>0</td>
<td>$ 0.00</td>
<td>0</td>
<td>[ Btn ]</td>
</tr>
@endforeach
@endforeach
</tbody>
</table>
这就是我在控制器方法中所拥有的。
$user = Auth::guard('user')->user();
$entries = TimeClock::select(
'pay_week',
'start_timestamp',
'total_duration'
)
->where('user_id', $user->record_id)
->get()
->groupBy('pay_week')
->map(function($entry) {
return (object)[
'count' => $entry->count(),
'duration' => $entry->sum('total_duration'),
//'year' => $entry->sum('start_timestamp')->year,
'entries' => $entry
];
});
return view('user.timeclock.reports.all', [
'entries' => $entries
]);
解决方案
鉴于,您在模型中设置了演员表
class TimeClock extends Model
{
protected $cast = [
'start_timestamp' => 'datetime'
];
}
您可以执行以下操作:
$entries = TimeClock::select(
'pay_week',
'start_timestamp',
'total_duration'
)
->where('user_id', $user->record_id)
//->groupBy('pay_week')
->get()
->groupBy([ 'pay_week', function($entry) {
return $entry->start_timestamp->year
})
/*->map(function($entry) {
return (object)[
'count' => $entry->count(),
'duration' => $entry->sum('total_duration'),
'year' => $entry->start_timestamp->year,
'entries' => $entry
];
})*/;
你像这样循环它:
<table>
<thead>
<tr>
<th>Pay week</th>
<th>Date range</th>
<th>Year</th>
<th>Total hours</th>
</tr>
</thead>
<tbody>
@foreach($entries as $pay_week => $groups)
@foreach($groups as $year => $group)
<!--pay_week: {{ $pay_week }}<br />
count: {{ $group->count() }}<br />
duration: {{ $group->sum('total_duration') }}<br />
year: {{ $year }}<br />-->
<tr>
<td>{{ $pay_week }}</td>
<td></td>
<td>{{ $year }}</td>
<td>{{ $group->sum('total_duration') }}</td>
</tr>
@foreach($group as $entry)
@endforeach
@endforeach
@endforeach
</tbody>
</table>
推荐阅读
- python - 多个while/尝试检查value是否是0到1之间的数组
- java - Intellij 更改“第一个建议修复”键?
- php - 设置多个身份验证保护时 Laravel 重定向错误
- javascript - 将特定单元格数据从工作表传输到工作表
- android - 如何延迟加载微调器并在协程内有条件地启动它?
- python - 比较两个 datetimestamp 列,如果该 datetimestamp 存在,则使用默认值创建新行 datetimestamp
- asp.net - 在 VS2015 和 VS2017 中打开解决方案时读取注册表的不同行为
- android - Xamarin.Android RecyclerView 提供数据库
- java - 获取特定程序的 JVM 属性
- c# - 在 Web 中检查 WCF 服务时出错