Mysql 在Laravel模型的关系中,如何使用GROUP BY和MAX返回关系?

Mysql 在Laravel模型的关系中,如何使用GROUP BY和MAX返回关系?,mysql,laravel,eloquent,laravel-5.4,Mysql,Laravel,Eloquent,Laravel 5.4,我有一个项目,该项目可以有附件。项目和文档都是模型/表 简化示例文档表: ----------------------------------- | ID | filename | version | ----------------------------------- | 1 | list.docx | 1 | | 2 | list.docx | 2 | | 3 | file.xls | 1

我有一个项目,该项目可以有附件。项目和文档都是模型/表

简化示例文档表:

-----------------------------------
| ID  | filename        | version |
-----------------------------------
| 1   | list.docx       | 1       |
| 2   | list.docx       | 2       |
| 3   | file.xls        | 1       |
-----------------------------------
我希望有一些简单的版本控制,这样如果用户想要,他们就可以“替换”文档,新表行复制除ID和版本之外的所有以前的条目值

我的问题是,我想使用关系来提取所有最新文档。我目前正在项目模型中使用这个怪物:

public function latest_documents()
{
    return $this->hasMany(Document::class)
        ->where('version', \DB::raw('(SELECT max(d.version) from documents d where d.filename = documents.filename)'))
}
一定有更好的办法吗?我试着在关系中使用groupBy和max,但出现了错误

编辑:在DB::raw解决方案之前尝试了“Laravel方法”:

public function documents()
{
    return $this->hasMany(Document::class)->groupBy('filename')->max('version');
}
错误:

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

我的建议是创建一个基于documents表的MySQL视图,该表始终只包含最新的文档文件,并与该视图建立关系。因此:

步骤1/创建视图:

create view latest_documents as
  select filename,
         max(version)  as version,
         project_id    as project_id,
         any_value(id) as id
  from documents
  group by project_id, filename;
步骤2/创建视图模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class LatestDocument extends Model
{
    //
}
我测试了这个,应该可以工作


注意:我在第一步中使用了任何_值,以防止仅根据_full_group_by发生错误。因此,如果您禁用了此模式,我建议您不必在id周围使用此功能。

请使用您尝试过的groupBy发布查询。@JonasStaudenmeir done,我认为这没有多大帮助!似乎不知道如何将行分组,然后选择具有最高/max versionId的行,请尝试$query->orderBy'version',desc'->groupBy'filename'@rkj发现此错误:SQLSTATE[42000]:语法错误或访问冲突:SELECT list的1055表达式1不在GROUP BY子句中,并且包含功能上不依赖GROUP BY子句中的列的未聚合列“app.documents.id”;这与sql\u mode=only\u full\u group\u by不兼容。您可以在config/database.php中添加'strict'=>false吗?然后尝试这样做的结果是,查询从documents表中找到最大版本号,然后只返回具有该版本的文档。@MikeK那么,在这种关系中,您到底要如何处理最大版本?是否要按其对文档进行排序?我要查找每个版本号最高的文件的条目,然后返回这些结果。但是,在DB条目之间,只有文件版本和ID会更改,其他字段如created_at等@MikeK我的建议是基于documents表创建一个MySQL视图,该表始终只包含最新的文档文件,并与该视图建立关系。@MikeK我在这里编辑了我的答案。请检查它是否有效。
public function latest_documents()
{
    return $this->hasMany(LatestDocument::class);
}