项目中有这样的需求,需要取出相同项目name的最新一个step
表tasks
id | name | step | created_at |
---|---|---|---|
1 | 项目 1 | 1 | 2019-05-03 10:00:00 |
2 | 项目 2 | 1 | 2019-05-03 10:00:01 |
3 | 项目 3 | 1 | 2019-05-03 10:00:02 |
4 | 项目 1 | 2 | 2019-05-03 10:00:03 |
如果使用Laravel查询语句:
Task::groupBy('name')->orderBy('created_at','DESC')->get();
但查询结果不是理想中的结果,返回项目1的step是1,不是2。
所以这种情况,需要用到子查询,SQL原生的语句应该这样写:
select * from (select * from tasks order by created_at desc) as a group by name;
Laravel Eloquent 子查询语法
$sql = Task::orderBy('created_at','DESC'); $lists = Task::select('*')->from(DB::raw('('.$sql->toSql().') as a'))->mergeBindings($sql->getQuery())->groupBy(['name'])->get();
如果结果也需要按照时间进行降序排序的话:
$lists = Task::select('*')->from(DB::raw('('.$sql->toSql().') as a'))->mergeBindings($sql->getQuery())->groupBy(['name'])->orderBy('created_at','DESC')->get();
问题汇总:
1、在高版本的mysql(mysql5.7或以上)里,如果出现子查询无效的情况,
解决方法:子查询里加上take
$sql = Task::orderBy('created_at','DESC')->take(10);
解析式这样的:通过 explain 查看执行计划,可以看到没有 limit 的时候,少了一个 DERIVED 操作。DERIVED用于派生表的SELECT(FROM子句的子查询),所以没有它就相当于子句里的排序并没有被执行。
2、当表模型里使用了软删除(use SoftDeletes),会报mysql错误“Column not found: 1054 Unknown column 'table.deleted_at' in 'where clause'”,但表是有deleted_at字段的
解决方法:加上“withoutGlobalScope('Illuminate\Database\Eloquent\SoftDeletingScope')”
$lists = Task::select('*')->from(DB::raw('('.$sql->toSql().') as a'))->mergeBindings($sql->getQuery())->withoutGlobalScope('Illuminate\Database\Eloquent\SoftDeletingScope')->groupBy(['name'])->get()
参考:
https://learnku.com/articles/20626
https://jingyan.baidu.com/article/4ae03de3df93cc3eff9e6b37.html
https://www.saoniuhuo.com/question/detail-2348168.html
本帖已被设为精华帖!