Laravel 按年月日分组查询结果(如果日期不存在则显示所有日期)
Laravel Group Query Result by Day on Month-Year (show all date if not exist date)
我有一个 table exampleTable
:
+------------+--------+
| created_at | result |
+------------+--------+
| 2021-05-21 | 3 |
| 2021-05-21 | 4 |
| 2021-05-22 | 5 |
| 2021-05-23 | 6 |
| 2021-05-23 | 7 |
我要结果:
+------------+--------+
| day | sumAll |
+------------+--------+
| 2021-05-01 | 0 |
| 2021-05-02 | 0 |
| 2021-05-03 | 0 |
....
| 2021-05-21 | 7 |
| 2021-05-22 | 5 |
| 2021-05-23 | 13 |
....
| 2021-05-29 | 0 |
| 2021-05-30 | 0 |
| 2021-05-21 | 0 |
这是我的查询:
$results = ExampleTable::select(
DB::raw("DATE_FORMAT(created_at,'%Y-%M-%d') as day"),
DB::raw('sum(result) as sumAll')
)
->whereMonth("created_at", '05')
->whereYear("created_at", '2021')
->groupBy('day')
->get();
但如果日期不存在则不会显示。
如果数据不存在,我想要带有日期和结果值的日期值设置为 0
- 通过
php artisan make:collection \App\Collections\ExampleCollection
创建一个新的 collection
- 执行以下操作:
<?php
namespace App\Collections;
use DatePeriod;
use Illuminate\Database\Eloquent\Collection;
class ExampleCollection extends Collection
{
public function withDefaults()
{
$date = $this->sortBy('day')[0]->day->firstOfYear();
$days = array_map(function($day) {
return $day->format('Y-m-d');
}, [...new DatePeriod("R11/{$date->toIso8601ZuluString()}/P1D")]); // e.g. 2021-01-01T00:00:00Z
$collection = array_fill_keys(array_fill_keys($days, []));
foreach($this as $item) {
$collection[$item->day->format('Y-m-d')] = $item;
}
return collect($collection);
}
}
- 在您的
ExampleTable
模型中添加:
public function newCollection(array $models = [])
{
return new ExampleCollection($models);
}
- 这样使用:
$results = ExampleTable::select(
DB::raw("DATE_FORMAT(created_at,'%Y-%M-%d') as day"),
DB::raw('sum(result) as sumAll')
)
->whereMonth("created_at", '05')
->whereYear("created_at", '2021')
->groupBy('day')
->get()
->withDefaults();
我有一个 table exampleTable
:
+------------+--------+
| created_at | result |
+------------+--------+
| 2021-05-21 | 3 |
| 2021-05-21 | 4 |
| 2021-05-22 | 5 |
| 2021-05-23 | 6 |
| 2021-05-23 | 7 |
我要结果:
+------------+--------+
| day | sumAll |
+------------+--------+
| 2021-05-01 | 0 |
| 2021-05-02 | 0 |
| 2021-05-03 | 0 |
....
| 2021-05-21 | 7 |
| 2021-05-22 | 5 |
| 2021-05-23 | 13 |
....
| 2021-05-29 | 0 |
| 2021-05-30 | 0 |
| 2021-05-21 | 0 |
这是我的查询:
$results = ExampleTable::select(
DB::raw("DATE_FORMAT(created_at,'%Y-%M-%d') as day"),
DB::raw('sum(result) as sumAll')
)
->whereMonth("created_at", '05')
->whereYear("created_at", '2021')
->groupBy('day')
->get();
但如果日期不存在则不会显示。
如果数据不存在,我想要带有日期和结果值的日期值设置为 0
- 通过
php artisan make:collection \App\Collections\ExampleCollection
创建一个新的 collection
- 执行以下操作:
<?php
namespace App\Collections;
use DatePeriod;
use Illuminate\Database\Eloquent\Collection;
class ExampleCollection extends Collection
{
public function withDefaults()
{
$date = $this->sortBy('day')[0]->day->firstOfYear();
$days = array_map(function($day) {
return $day->format('Y-m-d');
}, [...new DatePeriod("R11/{$date->toIso8601ZuluString()}/P1D")]); // e.g. 2021-01-01T00:00:00Z
$collection = array_fill_keys(array_fill_keys($days, []));
foreach($this as $item) {
$collection[$item->day->format('Y-m-d')] = $item;
}
return collect($collection);
}
}
- 在您的
ExampleTable
模型中添加:
public function newCollection(array $models = [])
{
return new ExampleCollection($models);
}
- 这样使用:
$results = ExampleTable::select(
DB::raw("DATE_FORMAT(created_at,'%Y-%M-%d') as day"),
DB::raw('sum(result) as sumAll')
)
->whereMonth("created_at", '05')
->whereYear("created_at", '2021')
->groupBy('day')
->get()
->withDefaults();