惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
H
Hacker News: Front Page
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cisco Blogs
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
S
Schneier on Security
The Hacker News
The Hacker News
Cyberwarzone
Cyberwarzone
T
Tenable Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Tailwind CSS Blog
S
Secure Thoughts
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
K
Kaspersky official blog
Google Online Security Blog
Google Online Security Blog
L
LangChain Blog
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
www.infosecurity-magazine.com
www.infosecurity-magazine.com
有赞技术团队
有赞技术团队
P
Privacy International News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Recent Announcements
Recent Announcements
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
G
Google Developers Blog
T
Threatpost
小众软件
小众软件
S
Securelist
Recent Commits to openclaw:main
Recent Commits to openclaw:main
O
OpenAI News

DigitalOcean Community Tutorials

Mastering grep with Regular Expressions for Efficient Text Search It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu How To Use Struct Tags in Go apt-key Deprecation: Add Repositories with GPG on Ubuntu Linux ps Command: 20 Real-World Examples Python struct.pack and struct.unpack for Binary Data Deadlock in Java: Examples, Detection, and Prevention How To Use Find and Locate to Search for Files on Linux Structured Resume Skill Extraction Using Mistral-7B Inference How to Use the Python Main Function How to Set Up NemoClaw on a DigitalOcean Droplet with 1-Click Build an End-to-End RAG Pipeline for LLM Applications From Single to Multi-Agent Systems: Key Infrastructure Needs Back Up Data to Object Storage Using Restic How to Generate Videos with LTX-2.3 on DigitalOcean GPU Droplets How To Install LAMP Stack (Apache, MySQL, PHP) on Ubuntu How to Download Files with cURL How To Use Variadic Functions in Go Generate UUIDs with uuidgen on Linux How To Use EJS to Template Your Node Application How to Install Node.js on Ubuntu (Step-by-Step Guide) MongoDB Indexes: Improve Query Performance with Node.js LLM Tool Calling with DigitalOcean AI Platform and Databases What are Text Diffusion Models? - An Overview Crafting a Game from Scratch with GPT-5.4 Building Long-Term Memory in AI Agents with LangGraph and Mem0 How To Install PHP 7.4 and Set Up a Local Development Environment on Ubuntu 20.04 Build a GraphQL API in Go to Upload Files to Spaces How To Lint and Format Code with ESLint in Visual Studio Code Train YOLO26 for Retail Object Detection on DigitalOcean GPUs How To Work with JSON in MySQL How to Use the JavaScript .map() Method Building a Scalable App with MongoDB Using DigitalOcean's MCP Server How to Create an SSH Key in Linux: Easy Step-by-Step Guide Measure MySQL Query Performance with mysqlslap How To Use *args and **kwargs in Python 3 Nemotron 3 helped me find the perfect dish rack? A2A vs MCP - How These AI Agent Protocols Actually Differ How To Install and Manage Supervisor Docker Container Images with Watchtower on Ubuntu Getting Started with Qwen3.5 Vision-Language Models How To Create a New Sudo-Enabled User on Ubuntu How to Use Ansible to Install and Set Up Docker on Ubuntu How To Enable Remote Desktop Protocol Using xrdp on Ubuntu 22.04 How To Convert a String to a List in Python How To Check If a String Contains Another String in Python How to Read a Properties File in Python Python Command Line Arguments: sys.argv, argparse, getopt Mastering Grep command in Linux/Unix: A Beginner's Tutorial Understanding Python Data Types How to Implement a Stack in C With Code Examples Python os.system() vs subprocess: Run System Commands How To Install and Use Docker Compose on Ubuntu How to Add and Delete Users on Ubuntu How To Define and Use Handlers in Ansible Playbooks How To Install and Use SQLite on Ubuntu How To Install and Use Homebrew on macOS How To Manage DateTime with Carbon in Laravel and PHP How To Install Git on Ubuntu How To Install and Secure Redis on Ubuntu How To Build and Install Go Programs on Linux Using ldflags to Set Version Information for Go Applications How To Build a Node.js Application with Docker How To Add JavaScript to HTML How To Reset Your MySQL or MariaDB Root Password How To Add Images in Markdown How To Set Up a Production Elasticsearch Cluster with Ansible How To Set Up a Firewall Using firewalld on CentOS Understanding Systemd Units and Unit Files How To Set Up Replication in MySQL How To Use the .htaccess File
How To Order Query Results in Laravel Eloquent
Anish Singh Walia · 2021-08-27 · via DigitalOcean Community Tutorials

Laravel Eloquent provides several methods to order query results directly at the database level, giving you full control over how records are sorted before they reach your application code. The orderBy() method is the most common way to add an ORDER BY clause to your Eloquent queries, but Laravel also offers convenience methods like orderByDesc(), latest(), oldest(), and orderByRaw() for different sorting needs.

In a previous part of this series, you learned how to obtain database records using the all() method from within an Eloquent model. You may recall using a method called sortDesc(), which was used to sort the records in descending order.

The sortDesc() method is part of the Collection class, a powerful Laravel utility class that works as an improved version of native PHP arrays. Instead of ordering results within the database query itself, this method inverts the order of a collection so that the last item appears first. While that works well for smaller result sets, it does not offer the same flexibility or performance as sorting the results in the database query itself.

This tutorial walks you through every ordering method available in Laravel Eloquent, from basic orderBy() usage to advanced techniques like raw SQL expressions and dynamic ordering with user input. You will also learn how ordering interacts with pagination and when to use collection-level sorting instead.

Key Takeaways

  • Use orderBy('column', 'direction') to sort Eloquent query results at the database level, which is more efficient than sorting PHP collections after retrieval.
  • latest() and oldest() are convenient shortcuts for ordering by timestamp columns without writing out the full orderBy() call.
  • Chain multiple orderBy() calls to sort by more than one column. Laravel applies the ordering in the sequence you chain them.
  • Use orderByRaw() with parameter bindings for complex SQL sorting expressions, and never pass unvalidated user input directly.
  • When accepting sort parameters from users, always validate column names against an allowlist and restrict direction values to asc or desc.

Prerequisites

To follow this tutorial, you need:

  • A local development environment for PHP and Laravel. If you are following the Eloquent series, you should have the demo Landing Laravel application set up with Docker Compose.
  • Familiarity with Eloquent models and basic query building.

Laravel Version Compatibility

The ordering methods covered in this tutorial (orderBy, orderByDesc, latest, oldest, orderByRaw) are available in Laravel 8 through the current Laravel 13. The syntax has remained stable across these versions. If you are using an older version, check the Laravel documentation for your specific release.

Understanding How Eloquent Handles Query Ordering

Before writing ordering queries, it helps to understand the two distinct approaches Laravel offers for sorting data: database-level ordering and collection-level sorting.

Database-Level Ordering vs. Collection-Level Sorting

Database-level ordering uses the SQL ORDER BY clause. When you call orderBy() on an Eloquent query builder, Laravel appends ORDER BY to the generated SQL statement. The database engine handles the sorting before returning results to PHP, which is efficient because databases are optimized for this operation.

Collection-level sorting happens in PHP after the data has already been fetched from the database. Methods like sortBy() and sortByDesc() operate on Eloquent Collections that are already loaded into memory.

For most use cases, database-level ordering is the better choice because the database can use indexes to speed up sorting. Collection-level sorting is useful when you need to reorder data that is already in memory or when sorting by a computed value that does not exist as a database column.

Default Ordering Behavior

When no ORDER BY clause is specified, databases do not guarantee any particular order of results. In practice, MySQL and PostgreSQL often return rows in primary key order, but this behavior is not reliable and can change based on query plans, indexes, or storage engine internals. Always specify an explicit order when the sequence of results matters to your application.

Using orderBy() to Sort Results Ascending and Descending

The orderBy() method is the primary way to sort query results in Laravel Eloquent. It translates directly to a SQL ORDER BY clause.

Syntax and Parameters

Model::orderBy('column_name', 'direction')->get();

The method accepts two arguments:

  • column_name (required): The database column to sort by.
  • direction (optional): Either 'asc' for ascending or 'desc' for descending. Defaults to 'asc' if omitted.

This generates the following SQL:

SELECT * FROM table_name ORDER BY column_name ASC|DESC;

Ordering in Ascending Order

Ascending order is the default. These two calls produce identical SQL:

// Explicit ascending
$users = User::orderBy('name', 'asc')->get();

// Implicit ascending (same result)
$users = User::orderBy('name')->get();

Both generate:

SELECT * FROM users ORDER BY name ASC;

Ordering in Descending Order

To sort from highest to lowest (or newest to oldest for dates), pass 'desc' as the second argument:

$posts = Post::orderBy('created_at', 'desc')->get();

This generates:

SELECT * FROM posts ORDER BY created_at DESC;

Applying orderBy() in the Demo Application

You will now change the code in your routes/web.php file to show results ordered from newest to oldest, based on the created_at table field.

Both the created_at and the updated_at fields are managed by Eloquent when you include a timestamps() definition in your table migration. You should not update these fields manually, but you can use them to sort and filter your queries.

Open this file in your code editor:

  1. routes/web.php

This is how the code looks now:

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links,
        'lists' => LinkList::all()
    ]);
})->name('link-list');

Notice that the /{slug} route, which is responsible for listing the links by slug, currently does not use any sorting method. Links are obtained through the list variable, highlighted in the code, using the relationship defined in the LinkList model.

If you add multiple links to a list now, the query will return results ordered from oldest to newest by default. Although you could use the sortDesc() method to reorder the collection within the $list->links call, using the orderBy() method provides more flexibility and allows you to include additional filtering conditions later. You can chain this method with a where() call for even more fine-grained results.

Replace the highlighted line in the previous code sample with the following line:

routes/web.php

'links' => $list->links()->orderBy('created_at', 'desc')->get(),

Notice that this time we are invoking the built-in query builder by calling the $list->links() method, which refers to the relationship method defined in the LinkList class. This is different from calling $list->links as a class property (without the parenthesis), which will invoke a magic method in the model to fetch all links related to that list.

This is how the full routes/web.php file should look once you are finished:

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links()->orderBy('created_at', 'desc')->get(),
        'lists' => LinkList::all()
    ]);
})->name('link-list');

Save and close the file. Now, add a couple new links using the link:new Artisan command. You can use the default list:

  1. docker-compose exec app php artisan link:new

Output

Link URL
: > https://laravel.com/docs/13.x/eloquent Link Description: > Laravel Eloquent Docs Link List (leave blank to use default): > New Link: https://laravel.com/docs/13.x/eloquent - Laravel Eloquent Docs Listed in: default Is this information correct? (yes/no) [no]: > yes Saved.

If you reload the default link list page, you should now obtain links from newest to oldest:

http://localhost:8000/default

Default Link List showing links ordered by creation date, in descending order - from newest to oldest

Likewise, if you would prefer to order links alphabetically by the link description, you would have to change the line to use that table field in the method call like this:

'links' => $list->links()->orderBy('description', 'asc')->get(),

This is how the links would be ordered after such change:

Default Link List showing links ordered alphabetically by link description

Using orderByDesc() as a Shorthand

The orderByDesc() method is a convenience wrapper around orderBy('column', 'desc'). It accepts a single argument: the column name.

When to Use orderByDesc()

Use orderByDesc() when you want descending order and prefer a shorter, more readable method call. The two approaches generate identical SQL:

// Using orderBy with desc direction
$posts = Post::orderBy('published_at', 'desc')->get();

// Using orderByDesc (same SQL output)
$posts = Post::orderByDesc('published_at')->get();

Both produce:

SELECT * FROM posts ORDER BY published_at DESC;

Code Example

Here is a practical example that fetches the five most recently updated products:

$recentProducts = Product::orderByDesc('updated_at')
    ->limit(5)
    ->get();

The generated SQL:

SELECT * FROM products ORDER BY updated_at DESC LIMIT 5;

Using latest() and oldest() for Timestamp-Based Ordering

Laravel provides latest() and oldest() as shorthand methods for ordering by timestamp columns. These are especially useful because ordering by created_at is one of the most common operations in web applications.

How latest() Maps to orderBy(‘created_at’, ‘desc’)

The latest() method is a shortcut for orderBy('created_at', 'desc'):

// These two queries produce identical SQL
$posts = Post::latest()->get();
$posts = Post::orderBy('created_at', 'desc')->get();

Both generate:

SELECT * FROM posts ORDER BY created_at DESC;

How oldest() Maps to orderBy(‘created_at’, ‘asc’)

The oldest() method is the inverse, equivalent to orderBy('created_at', 'asc'):

$posts = Post::oldest()->get();

Generates:

SELECT * FROM posts ORDER BY created_at ASC;

Specifying a Custom Column with latest() and oldest()

Both methods accept an optional column name argument if you want to order by a timestamp column other than created_at:

// Order by the most recently updated posts
$posts = Post::latest('updated_at')->get();

// Order by the earliest published posts
$posts = Post::oldest('published_at')->get();

These generate:

SELECT * FROM posts ORDER BY updated_at DESC;
SELECT * FROM posts ORDER BY published_at ASC;

Ordering by Multiple Columns

In many applications, you need to sort by more than one column. For example, sorting users by last name and then by first name for users who share the same last name.

Chaining Multiple orderBy() Calls

To order by multiple columns, chain orderBy() calls:

$users = User::orderBy('last_name', 'asc')
    ->orderBy('first_name', 'asc')
    ->get();

This generates:

SELECT * FROM users ORDER BY last_name ASC, first_name ASC;

Priority of Ordering

Laravel applies the ordering in the sequence you chain the methods. In the example above, the database first sorts by last_name. When multiple rows have the same last_name, the database then sorts those rows by first_name.

You can mix directions when chaining:

$orders = Order::orderBy('status', 'asc')
    ->orderByDesc('created_at')
    ->get();

This generates:

SELECT * FROM orders ORDER BY status ASC, created_at DESC;

Using orderByRaw() for Custom SQL Expressions

The orderByRaw() method lets you pass a raw SQL expression as the ORDER BY clause. This is useful when you need to sort by a computed value, a conditional expression, or a database function that Eloquent does not wrap natively.

Syntax and Use Cases

Model::orderByRaw('raw SQL expression')->get();

Common use cases include:

  • Sorting by the result of a database function (e.g., FIELD(), CASE WHEN)
  • Sorting by computed values (e.g., the difference between two columns)
  • Applying database-specific sorting logic

Passing Bindings to Prevent SQL Injection

When your raw expression includes values, always pass them as bindings through the second parameter. This prevents SQL injection:

$tasks = Task::orderByRaw('FIELD(status, ?, ?, ?)', ['urgent', 'active', 'closed'])
    ->get();

This generates a parameterized query:

SELECT * FROM tasks ORDER BY FIELD(status, 'urgent', 'active', 'closed');

The FIELD() function (available in MySQL) returns the position of the first argument in the subsequent list, which lets you define a custom sort order.

Warning: Never pass user-supplied column names or direction values directly into orderByRaw(). Always validate and sanitize any external input before including it in raw SQL expressions. Use the dynamic ordering approach described later in this tutorial for handling user input safely.

Example: Ordering by a Computed Expression

Sort orders by the time difference between when they were last updated and when they were created:

$orders = Order::orderByRaw('updated_at - created_at DESC')->get();

This generates:

SELECT * FROM orders ORDER BY updated_at - created_at DESC;

The updated_at - created_at syntax works in MySQL and PostgreSQL. If you are using SQL Server, you would need DATEDIFF(second, created_at, updated_at) instead.

Sorting Eloquent Collections with sortBy() and sortByDesc()

Sometimes you need to sort data that is already loaded in memory. Laravel’s Collection class provides sortBy() and sortByDesc() for this purpose.

When Collection Sorting Is Appropriate

Collection-level sorting makes sense when:

  • You already have the data loaded and do not want to run another database query.
  • You need to sort by a computed value that exists only in PHP (for example, a value derived from a model accessor).
  • The dataset is small enough that sorting in PHP will not cause performance issues.

Performance Trade-Offs Versus Query-Level Ordering

For large datasets, database-level ordering with orderBy() is significantly faster because:

  • The database can use indexes to speed up sorting.
  • Only the sorted result set is transferred to PHP, reducing memory usage.
  • PHP’s sorting algorithms operate in memory and do not benefit from database indexes.

As a general rule, use orderBy() at the query level whenever possible. Reserve collection sorting for small datasets or situations where the sort criteria cannot be expressed in SQL.

Sorting by Nested or Computed Values Using a Callback

You can pass a callback to sortBy() for custom sorting logic:

$links = Link::all();

// Sort by the length of the description
$sorted = $links->sortBy(function ($link) {
    return strlen($link->description);
});

// Sort by a related model's attribute
$sorted = $links->sortBy(function ($link) {
    return $link->link_list->title;
});

The sortByDesc() method works the same way but in reverse order:

$sorted = $links->sortByDesc('created_at');

Collection sorting returns a new collection and does not modify the original. The sort methods also preserve array keys. If you need re-indexed keys, chain ->values() after sorting.

Dynamic Ordering with User-Supplied Input

In many applications, users expect to sort tables or lists by clicking column headers. Implementing this requires accepting the column name and sort direction from the HTTP request, but you must validate these inputs to prevent SQL injection and unexpected errors.

Validating Column Names Against an Allowlist

Never pass a user-supplied column name directly to orderBy(). Instead, check it against an explicit list of allowed columns:

$allowedColumns = ['name', 'email', 'created_at', 'updated_at'];
$sortColumn = in_array($request->input('sort'), $allowedColumns)
    ? $request->input('sort')
    : 'created_at';

Validating Direction Input

Restrict the direction value to only asc or desc:

$sortDirection = $request->input('direction') === 'asc' ? 'asc' : 'desc';

Code Example with Request Input

Here is a complete route example that handles dynamic ordering safely:

Route::get('/users', function (Illuminate\Http\Request $request) {
    $allowedColumns = ['name', 'email', 'created_at'];
    $allowedDirections = ['asc', 'desc'];

    $sortColumn = in_array($request->input('sort'), $allowedColumns)
        ? $request->input('sort')
        : 'created_at';

    $sortDirection = in_array($request->input('direction'), $allowedDirections)
        ? $request->input('direction')
        : 'desc';

    $users = User::orderBy($sortColumn, $sortDirection)->paginate(20);

    return view('users.index', ['users' => $users]);
});

A request to /users?sort=name&direction=asc generates:

SELECT * FROM users ORDER BY name ASC LIMIT 20 OFFSET 0;

Combining orderBy() with paginate()

Ordering and pagination work together naturally in Laravel. When you chain orderBy() before paginate(), Laravel preserves the sort order across all pages of results.

How Ordering Is Preserved Across Paginated Result Sets

Laravel’s paginate() and simplePaginate() methods automatically append the ORDER BY clause to every paginated query. The pagination links generated by these methods include the necessary query parameters to maintain the current page context.

Code Example: Paginated and Ordered Post List

Route::get('/posts', function () {
    $posts = Post::orderBy('created_at', 'desc')->paginate(15);

    return view('posts.index', ['posts' => $posts]);
});

This generates a query like:

SELECT * FROM posts ORDER BY created_at DESC LIMIT 15 OFFSET 0;

On subsequent pages, the offset changes while the ordering remains consistent:

SELECT * FROM posts ORDER BY created_at DESC LIMIT 15 OFFSET 15;

In your Blade template, render the pagination links:

{{ $posts->links() }}

For more details on implementing pagination in Laravel, see the How To Limit and Paginate Query Results in Laravel Eloquent tutorial.

Quick Reference: Eloquent Ordering Methods Compared

The following table summarizes all ordering methods available in Laravel Eloquent:

Method Default Direction Typical Use Case SQL Equivalent
orderBy('col', 'asc') asc General-purpose ascending sort ORDER BY col ASC
orderBy('col', 'desc') N/A (explicit) General-purpose descending sort ORDER BY col DESC
orderByDesc('col') desc Shorthand for descending sort ORDER BY col DESC
latest() desc Newest records by created_at ORDER BY created_at DESC
latest('col') desc Newest records by custom column ORDER BY col DESC
oldest() asc Oldest records by created_at ORDER BY created_at ASC
oldest('col') asc Oldest records by custom column ORDER BY col ASC
orderByRaw('expr') N/A (raw) Complex or computed expressions ORDER BY expr
reorder() N/A Remove all existing ordering Removes ORDER BY clause
reorder('col', 'dir') N/A Replace existing ordering Replaces ORDER BY clause

Collection-level methods (operate on data already in PHP memory):

Method Direction Typical Use Case
sortBy('col') Ascending Re-sort a loaded collection
sortByDesc('col') Descending Re-sort a loaded collection in reverse
sortBy(callback) Ascending Sort by computed or nested value

FAQs

1. How do you ORDER BY a query in Laravel Eloquent?

Use the orderBy('column', 'direction') method before calling get() or paginate(). The direction parameter accepts 'asc' for ascending or 'desc' for descending, and defaults to 'asc' if omitted:

$users = User::orderBy('name', 'asc')->get();

This appends ORDER BY name ASC to the generated SQL query.

2. What is the difference between orderBy() on a query and sortBy() on a Collection?

orderBy() adds an ORDER BY clause to the SQL query and runs at the database level. sortBy() is called on a PHP Collection object after the data has already been fetched. For large datasets, orderBy() is more efficient because the database engine handles sorting using indexes. sortBy() is best for small datasets or when you need to re-sort data that is already in memory.

3. How do you order by multiple columns in Laravel Eloquent?

Chain multiple orderBy() calls. Laravel applies the ordering in the sequence the methods are chained:

$users = User::orderBy('last_name', 'asc')
    ->orderBy('first_name', 'asc')
    ->get();

This produces ORDER BY last_name ASC, first_name ASC in the generated SQL. The database first sorts by last_name, then by first_name for rows where last_name is identical.

4. Is orderByRaw() safe to use with user input?

Not directly. Never pass user-supplied column names or direction values into orderByRaw() without validation. For expressions that require value bindings, use the second parameter to pass bindings safely:

Task::orderByRaw('FIELD(status, ?, ?)', ['active', 'inactive'])->get();

For user-controlled column names and directions, use orderBy() with an allowlist as described in the Dynamic Ordering section of this tutorial.

5. What do latest() and oldest() do in Laravel Eloquent?

latest() is shorthand for orderBy('created_at', 'desc') and returns the most recent records first. oldest() is shorthand for orderBy('created_at', 'asc') and returns the earliest records first. Both methods accept an optional column name argument if you need to order by a timestamp column other than created_at:

Post::latest('published_at')->get();

Conclusion

In this tutorial, you learned how to order query results in Laravel Eloquent using orderBy(), orderByDesc(), latest(), oldest(), and orderByRaw(). You also explored how to sort by multiple columns, handle dynamic user input safely, combine ordering with pagination, and choose between database-level ordering and collection-level sorting.

The key principle to keep in mind: sort at the database level with orderBy() whenever possible, and reserve collection-level sorting with sortBy() for small datasets or computed values that cannot be expressed in SQL.

In the next part of this series, you will learn how to get the total result count from a Laravel Eloquent query.

Continue Learning

If you want to keep building on these concepts, explore the following DigitalOcean resources:

You can also deploy your Laravel application on DigitalOcean App Platform, which provides a fully managed infrastructure for PHP applications with built-in support for managed databases. If you need a dedicated database, DigitalOcean Managed Databases offers MySQL and PostgreSQL clusters with automated backups and scaling.

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.