Hỏi về eloquent trong laravel
Em có bảng History lưu trữ thông tin. Em muốn đọc data từ bảng ra theo 12 tháng. Ví dụ năm nay là 2021. Input là 2021 output là 12item tương đương với 12 tháng. Nhưng hiện tại mới là tháng 8 thì chỉ đọc ra đc 8 tháng, em muốn 4 tháng còn lại vẫn đọc ra và giá trị của nó bằng 0. Có cách nào không ạ. Em cảm ơn
4 CÂU TRẢ LỜI
// Đây là ví dụ của mình bạn có thể tham khảo thử
function get HistoryByYear($year) {
$months = [];
for($i = 0; $i < 12; $i++) {
$months[] = History::whereYear('created_at', $year)
->whereMonth('created_at', $i)
->get()->toArray();
}
return $months;
}
Cách làm ở trên vẫn chạy tốt nhưng sẽ chạy tận 12 câu query. Bạn thử get data groupBy theo tháng. Sau đó tạo thêm 1 cái array từ tháng 1 đến tháng 12. Rồi xét index. cái nào k trùng index với data đã lấy ra thì cho nó bằng 0 thử xem sao
@lehuyvuong đồng quan điểm ! nên dùng groupBy + dùng array để check và merge data vào
Mình thấy là dữ liệu bạn đọc ra từ CSDL bằng Eloquent là dạng Collection, nếu bạn muốn thêm 4 tháng còn lại thì chỉ cần add thêm data vào Collection bằng phương thức put
là được, bạn có thể xem cách sử dụng của phương pháp này ở link này nha https://laravel.com/docs/8.x/collections#method-put. Nhưng theo mình thì việc đọc ra 8 tháng và hiển thị ra 8 tháng hợp lí hơn mà nhỉ, hiển thị 12 tháng và để rỗng nó không có ý nghĩa nhiều lắm.
History::whereYear('created_at', $year)->groupBy(function($d) {
return Carbon::parse($d->created_at)->format('m');
})->get();
SELECT t2.month, COUNT(t1.id) FROM histories t1
RIGHT JOIN (
SELECT 1 AS month UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) t2
ON MONTH(t1.created_at) = t2.month AND YEAR (t1.created_at) = 2020
group by t2.month;
Bạn có thể tham khảo SQL để convert sang ELOQUENT hoạc dùng DB RAW để lấy dữ liệu