Laravel Eloquent - Sort Collection by Column by Array's Order
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Laravel Eloquent: Sorting Collections by Custom Array Order
As we dive deeper into building complex data applications with Laravel, one of the most common challenges developers face is not just sorting data by a single column, but imposing a custom, prioritized order across multiple criteria. You want your pending items to float to the top, followed by active items, and then archived items—a specific sequence that standard orderBy() often cannot handle directly.
This post will explore how to achieve this complex sorting requirement for your Eloquent collections, moving beyond simple alphabetical or numerical sorting to implement custom prioritization using database queries.
The Challenge: Prioritized Sorting
The core problem is transforming a simple sort (e.g., ORDER BY status) into a hierarchical sort based on an external priority list, such as prioritizing statuses like Pending (2), Draft (1), and Published (3). We need the database to respect this custom sequence when retrieving results.
For instance, if you have a column named status with values 'pending', 'draft', and 'published', and you want the order to be: Pending first, then Draft, then Published, we need a mechanism to map these string values to numerical priorities before sorting.
Solution 1: Leveraging Database Raw Expressions (The Efficient Way)
The most performant way to handle complex, multi-conditional sorting is to let the database engine do the heavy lifting. Instead of loading all data into PHP and sorting it in memory (which can be slow for large datasets), we instruct the database to calculate a sort value based on your custom logic. This is best achieved using DB::raw() within the Eloquent query.
Let's assume you have a table where the status is stored as an integer or string, and you maintain a separate configuration mapping that defines the desired order:
// Hypothetical Priority Mapping (e.g., Pending=2, Draft=1, Published=3)
$priorityMap = [
'pending' => 2,
'draft' => 1,
'published' => 3,
];
To implement this sort, we can use a CASE statement in the SQL query to assign a numerical rank to each status based on our desired priority.
use Illuminate\Support\Facades\DB;
use App\Models\YourModel;
class ListingService
{
public function getPrioritizedList(array $priorityMap)
{
// 1. Prepare the sorting logic using DB::raw()
$orderByExpression = DB::raw("CASE status
WHEN ? THEN 2 -- Priority for Pending is highest
WHEN ? THEN 1 -- Priority for Draft is next
WHEN ? THEN 3 -- Priority for Published is lowest
ELSE 99
END ASC");
// 2. Execute the query using the custom expression
$results = YourModel::select('*')
->orderBy(DB::raw("CASE status
WHEN 'pending' THEN 2
WHEN 'draft' THEN 1
WHEN 'published' THEN 3
ELSE 99
END ASC"))
->get();
return $results;
}
}
Why this works: By injecting the CASE statement directly into the orderBy() method, we instruct MySQL (or PostgreSQL) to sort the rows based on the calculated numerical result of that expression, effectively bypassing a simple alphabetical sort and enforcing our custom priority order. This approach keeps the sorting logic entirely on the database side, which is significantly more efficient than filtering and sorting massive collections in PHP memory.
Solution 2: Post-Collection Sorting (For Smaller Datasets)
If your dataset is relatively small and performance is not the absolute primary concern, you could fetch the data first and then sort the resulting collection using standard PHP methods. This method is simpler to write but scales poorly for large tables.
$items = YourModel::all();
// Define the custom order explicitly
$customOrder = ['pending', 'draft', 'published'];
usort($items, function ($a, $b) use ($customOrder) {
$orderA = array_search($a->status, $customOrder);
$orderB = array_search($b->status, $customOrder);
// Sort based on the index found in our custom order array
return $orderA <=> $orderB;
});
// $items is now sorted by priority
While this method works perfectly for demonstration, it’s generally discouraged for high-traffic scenarios where Eloquent's power—especially when dealing with complex relationships and large result sets—should be utilized fully. For robust data retrieval patterns, always favor database-level sorting whenever possible, as highlighted in the documentation on efficient query building from laravelcompany.com.
Conclusion
For implementing custom, prioritized sorting in Laravel Eloquent, the recommended approach is to push the logic down to the database using DB::raw() expressions. This ensures optimal performance by leveraging SQL engine capabilities instead of relying on PHP memory operations. By structuring your queries this way, you maintain clean, readable code while achieving highly efficient data ordering, making complex filtering and sorting a straightforward task within the Laravel ecosystem.