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);
}