简体   繁体   English

Laravel Eloquent,按月/年分组

[英]Laravel Eloquent, group by month/year

i'm trying to group my data by month and year.我正在尝试按月和年对数据进行分组。

$data ->select(DB::raw('count(id) as `data`'),DB::raw('YEAR(created_at) year, MONTH(created_at) month'))
           ->groupby('year','month')
           ->get();

The output is: output 是:

{
"data": 19215,
"year": 2016,
"month": 10
},

if i group only by month, i don't know from which year belong this month, my expected output is:如果我只按月份分组,我不知道这个月属于哪一年,我预期的 output 是:

{
"clicks": 19215,
"month": 11-2016,
},
{
"clicks": 11215,
"month": 12-2016,
},

i want to do it in sql, not in php.我想在 sql 中进行,而不是在 php 中进行。

You can try as:您可以尝试如下:

->select(DB::raw('count(id) as `data`'), DB::raw("DATE_FORMAT(created_at, '%m-%Y') new_date"),  DB::raw('YEAR(created_at) year, MONTH(created_at) month'))
->groupby('year','month')
->get();

Note: This is solution based on eloquent, and yes, it not the best approach, but as the question is, this is using eloquent.注意:这是基于 eloquent 的解决方案,是的,它不是最好的方法,但问题是,这是使用 eloquent。 If you want faster way, you can do it with raw query.如果您想要更快的方式,您可以使用原始查询来完成。

If you want to group your results for example by year, you can use closure where you will parse your datetime to desired format (year or month).如果您想按年份对结果进行分组,则可以使用闭包将日期时间解析为所需的格式(年或月)。

Here is example of the code:以下是代码示例:

$res= ModelName::where('someColumn','test')
      ->get()
      ->groupBy(function($val) {
      return Carbon::parse($val->created_at)->format('Y');
});
$result = ModelName::selectRaw('year(created_at) year, monthname(created_at) month, count(*) data')
                ->groupBy('year', 'month')
                ->orderBy('year', 'desc')
                ->get();
$data ->select(DB::raw('count(id) as `data`'),DB::raw('YEAR(created_at) year'),DB::raw('MONTH(created_at) month'))
       ->groupBy(DB::raw('YEAR(created_at)'), DB::raw('MONTH(created_at)'))
       ->get();

=>this might help someone in 2019 =>这可能对 2019 年的某人有所帮助

$date = "2019-06-16";

return date('m', strtotime($date)); //this return you 06(edited)

so you can do foreach by this method , so you don't need to do the all sql things..所以你可以通过这种方法来做 foreach,所以你不需要做所有的 sql 事情..

for latest version of mysql, the accepted answer will give error, so instead try对于最新版本的 mysql,接受的答案将给出错误,因此请尝试

$data
    ->selectRaw("
        count(id) AS data, 
        DATE_FORMAT(created_at, '%Y-%m') AS new_date, 
        YEAR(created_at) AS year, 
        MONTH(created_at) AS month
    ")
    ->groupBy('new_date')
    ->get();

ref: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format参考: https : //dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format

The answer by @Amit Gupta is a good, but it isn't working >= MySQL 5.7/MariaDB 10.2 and calls the error: @Amit Gupta 的回答很好,但它不起作用 >= MySQL 5.7/MariaDB 10.2 并调用错误:

Syntax error or access violation: 1055 Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column语法错误或访问冲突:SELECT 列表的 1055 表达式 #2 不在 GROUP BY 子句中并且包含非聚合列

To solve that issue, you can use eg.要解决该问题,您可以使用例如。 MIN() on the nonaggregated column:非聚合列上的MIN()

->select(
    DB::raw("
    count(id) as data, 
    MIN(DATE_FORMAT(created_at, '%m-%Y')) as new_date, 
    YEAR(created_at) year, 
    MONTH(created_at) month
    ")
)
->groupBy('year', 'month')
->get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM