Laravel Query Builder Reference Guide
A reference guide to Laravel's fluent query builder for reading and writing data without raw SQL.
Laravel Reference
Fundamentals
Data
Validation & Security
Automation & Communication
Getting started
The DB facade gives you a fluent interface for building and running queries against any configured database connection, without writing raw SQL by hand. Every method returns the query builder itself (except the terminal methods like get()), so calls chain together.
use Illuminate\Support\Facades\DB;
$users = DB::table('users')->get();
$user = DB::table('users')->where('id', 1)->first();
$name = DB::table('users')->where('id', 1)->value('name');
$exists = DB::table('users')->where('email', $email)->exists();
Select clauses
DB::table('users')->select('id', 'name', 'email')->get();
DB::table('users')->select('name as full_name')->get();
DB::table('users')->distinct()->pluck('country');
Where clauses
The most common way to filter results. Chain multiple where() calls to combine them with AND; use orWhere() for OR.
DB::table('users')
->where('active', true)
->where('age', '>=', 18)
->orWhere('role', 'admin')
->get();
DB::table('users')->whereIn('id', [1, 2, 3])->get();
DB::table('users')->whereNotIn('id', [1, 2, 3])->get();
DB::table('users')->whereBetween('age', [18, 30])->get();
DB::table('users')->whereNull('deleted_at')->get();
DB::table('users')->whereNotNull('email_verified_at')->get();
DB::table('posts')->whereDate('created_at', '2026-01-01')->get();
// Group conditions with a closure to control operator precedence
DB::table('users')->where(function ($query) {
$query->where('role', 'admin')
->orWhere('role', 'manager');
})->where('active', true)->get();
Ordering, grouping, and limiting
DB::table('users')->orderBy('name')->get();
DB::table('users')->orderByDesc('created_at')->get();
DB::table('users')->latest()->first(); // orderBy('created_at', 'desc')
DB::table('users')->oldest()->first();
DB::table('orders')
->select('customer_id', DB::raw('SUM(total) as total_spent'))
->groupBy('customer_id')
->having('total_spent', '>', 1000)
->get();
DB::table('users')->skip(10)->take(5)->get();
DB::table('users')->paginate(15);
Joins
DB::table('users')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.name', 'orders.total')
->get();
DB::table('users')
->leftJoin('orders', 'users.id', '=', 'orders.user_id')
->get();
Aggregates
DB::table('orders')->count();
DB::table('orders')->max('total');
DB::table('orders')->min('total');
DB::table('orders')->avg('total');
DB::table('orders')->sum('total');
Inserts, updates, and deletes
DB::table('users')->insert([
'name' => 'Jane Doe',
'email' => 'jane@example.com',
]);
$id = DB::table('users')->insertGetId([
'name' => 'Jane Doe',
]);
DB::table('users')->where('id', 1)->update(['votes' => 1]);
DB::table('users')->where('votes', '<', 100)->increment('votes', 5);
DB::table('users')->where('id', 1)->delete();
Raw expressions
Drop down to raw SQL fragments when the fluent methods don't cover what you need — but prefer bindings (? placeholders) over string-interpolating user input to avoid SQL injection.
DB::select('select * from users where active = ?', [true]);
DB::table('users')
->whereRaw('age > ? and active = ?', [18, true])
->get();