Laravel对数据库结果进行分组和排序

时间:2020-01-20 16:35:11

标签: php sql laravel eloquent laravel-6

说我有下表...

+----+---------------------+---------+---------------------+
| id | slug                | version | created_at          |
+----+---------------------+---------+---------------------+
| 1  | url-friendly-string | 1.0.0   | 2020-01-19 01:00:00 |
+----+---------------------+---------+---------------------+
| 2  | url-friendly-string | 1.0.0   | 2020-01-19 02:00:00 |
+----+---------------------+---------+---------------------+
| 3  | url-friendly-string | 1.0.1   | 2020-01-20 00:00:00 |
+----+---------------------+---------+---------------------+
| 4  | another             | 0.0.1   | 2020-01-20 00:30:00 |
+----+---------------------+---------+---------------------+
| 5  | another             | 0.0.2   | 2020-01-20 01:00:00 |
+----+---------------------+---------+---------------------+

可能存在多个具有相同slugversion的条目,我想获得按slug分组的每个项目的最新,最高版本。例如,最终结果看起来有点像...

$collection = Array(
    Object(
        'slug' => 'another',
        'version' => '0.0.2',
        'created_at' => '2020-01-20 01:00:00'
    ),
    Object(
        'slug' => 'url-friendly-string',
        'version' => '1.0.1',
        'created_at' => '2020-01-20 00:00:00'
    )
)

我尝试了以下方法...

1。

$collection = auth()->user()
    ->items()
    ->orderBy('created_at', 'desc')
    ->orderBy('version', 'desc')
    ->groupBy('slug', 'version')
    ->get();

哪个会产生:

语法错误或访问冲突:1055 SELECT列表的表达式#1不在GROUP BY子句中,并且包含未聚合的列

可以在以下位置找到有关此错误的良好答案:browser developer tools

2。

$collection = auth()->user()
    ->items()
    ->orderBy('created_at', 'desc')
    ->orderBy('version', 'desc')
    ->get()
    ->groupBy('slug', 'version')
    ->map(function($group) {
        return $group->first();
    });

这是一种作品,但可能会产生不正确的排序。


如何到达需要去的地方?

这是一个新项目,因此销毁表等不是问题。

1 个答案:

答案 0 :(得分:0)

您可以先通过子查询对表格进行排序,请尝试以下操作:

$subSql = DB::table('my_table')->orderBy('version', 'desc')->toSql();

$result = DB::table( DB::raw("({$subSql}) as subQuery") )
    ->groupBy('slug')
    ->get();