Laravel 按月年日分组查询结果(如果不存在日期则显示所有日期)

问题描述 投票:0回答:1

我有一张桌子

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 mysql laravel laravel-query-builder
1个回答
0
投票
  1. 通过
    php artisan make:collection \\App\\Collections\\ExampleCollection
  2. 创建新集合
  3. 执行以下操作:
<?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);
    }
}

  1. 在您的
    ExampleTable
    模型中添加以下内容:
    public function newCollection(array $models = [])
    {   
        return new ExampleCollection($models);
    }
  1. 像这样使用它:
$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();
© www.soinside.com 2019 - 2024. All rights reserved.