在 Laravel 中,Eloquent 提供了方便的 Query Builder 讓我們可以動態查詢資料。如果我們希望 讓特定 id 排在前面,其他資料按照時間排序,可以使用 orderByRaw 搭配 FIELD() 函數來實現。

目標

我們要在 Eloquent Query Builder 中:

  1. 取得 agency_id 對應的資料

  2. 讓特定的 girl_id 排在最前面

  3. 其餘資料按照 created_at 由新到舊排序

方法 1:基本用法

如果你已經有一個 Eloquent 模型,例如 GirlAgencyPhoto,可以這樣查詢:

$priorityGirlIds = [7, 3, 10]; // 這些 girl_id 需要排在最前面
$agency_id = 1; // 要查詢的 agency_id

$photos = GirlAgencyPhoto::where('agency_id', $agency_id)
    ->orderByRaw("FIELD(girl_id, " . implode(',', $priorityGirlIds) . ") DESC")
    ->orderBy('created_at', 'desc')
    ->get();

說明

  1. where('agency_id', $agency_id):篩選符合 agency_id 的資料。

  2. orderByRaw("FIELD(girl_id, ...")

    • $priorityGirlIds 內的 girl_id 排在最前面。

    • FIELD(girl_id, 7, 3, 10) 會讓 girl_id = 7310 的資料優先排序。

  3. orderBy('created_at', 'desc')

    • 其餘 girl_id 的資料依照 created_at 降冪排序(最新的在前)。

 

方法 2:包裝成 Eloquent Model 方法

如果這段程式碼會經常使用,建議封裝成 Model 靜態函式,這樣程式碼更整潔、更好維護。

修改 GirlAgencyPhoto Model

class GirlAgencyPhoto extends Model
{
    protected $table = 'girl_agency_photos';

    public static function getCachedAgencyPhotos($agency_id, array $priorityGirlIds = [])
    {
        return Cache::remember('girl_photos_' . $agency_id, 86400, function () use ($agency_id, $priorityGirlIds) {
            $query = self::where('agency_id', $agency_id);

            if (!empty($priorityGirlIds)) {
                $query->orderByRaw("FIELD(girl_id, " . implode(',', $priorityGirlIds) . ") DESC");
            }

            return $query->orderBy('created_at', 'desc')->get();
        });
    }
}

 

如何使用這個方法

當你需要查詢資料時,只需要這樣呼叫:

$agency_id = 1;
$priorityGirlIds = [7, 3, 10];

$photos = GirlAgencyPhoto::getCachedAgencyPhotos($agency_id, $priorityGirlIds);

 

這樣的優點

封裝在 Model 中:讓查詢更容易維護,避免重複寫相同的查詢語法。
支援快取:使用 Cache::remember(),減少頻繁查詢資料庫的負擔。
支援靈活排序:傳入不同的 $priorityGirlIds,可動態調整排序方式。