やってみた
date
カラムから年度に変換し、重複を削除、値(年度)を降順ソートしました。
※date
カラムに存在する年度のみ取得します。
一般的な年度(4月1日~翌年3月31日までを年度)とします。
※2019年を例にすると、2019年4月1日から2020年3月31日までのことを指します。
$dates = Status::pluck('date');
foreach ($dates as $date) {
$array[] = $date->subMonthsNoOverflow(3)->format('Y');
}
$years = collect($array)->unique()->sort()->reverse()->values();
dd($years);
sort()について
最初、->values()->sortByDesc('date');
でできるかな~と思ってのですが下記のように…
dd($years);
の取得結果
↑ 求めてるソートにならない!なんでだ~~と日本語ドキュメントを見て試行錯誤したのですが、降参!!!
@mpywさんに相談し教えていただきました(いつも有難うございます。)!
値(年度)を降順で表示!
->sort()->reverse()->values();
・pluckの時点で中身取り出している
・sortBy は2次元配列想定してるけど既に1次元配列になってる
・生PHPの場合はsort関数に対応してrsort関数とかあったりはする
・collectionは逆順ソート用のメソッドがないので,昇順ソートしてから配列を逆に並べてる
とのことでした。。
これで求めてる値(年度)のソートになりました!👏
ちなみにどうしてもsortByDesc
を使うのであれば、pluckの前につけると使えるみたいですが、
sortByDesc('date')->pluck('date')
メモリ消費するのであまりおすすめできないそうです!
map()を使った方法
コメントより、kiyoamiさんに教えていただきました。
$years = Status::pluck('date')->map(function ($date) {
return $date->subMonthsNoOverflow(3)->format('Y');
})->unique()->sort()->reverse()->values();
dd($years);
クエリビルダを使った方法
kiyoamiさんに教えていただきました。度々ありがとうございます!
こちらは年度ではなく、年(2020年➡2020年1月1日~2020年12月31日まで)を取得します。
$years = Status::selectRaw('year(`date`) `yyyy`')->distinct()->groupBy('date')->pluck('yyyy');
dd($years);
プルダウンに年度を表示させたい場合
<select name="year">
@foreach($years as $key => $name)
<option value="{{ $name }}"{{old('year', $year) == $name ? 'selected' : ''}}>{{ $name }}</option>
@endforeach
</select>
ひとまずこれで年度を取得し配列に入れて表示する、までは完成です。
次は年度からデータを取得する場合
例えば年度の絞り込みがあったときです。
Statusテーブルのdate
カラムから、(任意)年の4月1日~翌年3月31日のデータを取得します。
$year = $request->input('year');
$status = Status::query();
if (!empty($year)) {
$startAt = CarbonImmutable::createMidnightDate($year, 4, 1);
$endAt = $startDate->day(1)->addMonths(11)->endOfMonth();
$status->whereBetween('date', [$startAt, $endAt]);
}
$year
に2015
が入ってきた場合、$startAt
と$endAt
は以下となります。
参考文献
この記事は以下の情報を参考にしました。