Laravel 分組獲取最新記錄

chaosir發表於2018-12-04

前言

今天專案中需要根據分組查詢最新記錄的業務邏輯,想要使用 Eloquent 查詢出來,做個記錄。

實現

表內容

id name user_id value
1 專案1 61 測試內容1
2 專案2 61 測試內容2
3 專案3 61 測試內容3
4 專案1 61 測試內容123

原生 SQL 為:

select * from (select * from project where user_id = :user_id order by id desc) as a group by a.name order by id desc;

Mysql5.7 查出來的結果為

id name user_id value
3 專案3 61 測試內容3
2 專案2 61 測試內容2
1 專案1 61 測試內容1

原因是 5.7 版本 ORDER BY 沒有 LIMIT 的時候,少了一個 DERIVED 操作,估計是內部最佳化了,認為 ORDER BY 在這種語法中可忽略,有 LIMIT 限制涉及排序後的結果,不會忽略 ORDER BY,可以達到預期。

最佳化後得到

select * from (select * from project where user_id = :user_id order by id desc limit 10000) as a group by a.name order by id desc;

查詢結果為

id name user_id value
4 專案1 61 測試內容123
3 專案3 61 測試內容3
2 專案2 61 測試內容2

Eloquent 子查詢語法

<?php

public function projectList(Request $request){
        $limit = $request->get('limit',10);
        $user_id = $request->get('user_id',null);

        $sub_query = Project::where('user_id',$user_id)->orderBy('id','desc')->limit(1000);//子查詢

        $results = Project::select('*')
                ->from(DB::raw('('.$sub_query->toSql().') as a')) //from() 類似與 DB::table(), toSql()得到帶 ? 號的執行 sql 語句
                ->mergeBindings($sub_query->getQuery())//mergeBindings() 合併繫結引數,getQuery()獲得具體值
                ->groupBy('name')
                ->orderBy('id','desc')
                ->paginate($limit);

        return $this->pageDate($results);
    }
?>
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章