Skip to main content

What is Querying?

Querying is how you ask your database for specific information. Instead of getting all records, you can filter, sort, and limit results to get exactly what you need.
Real-world analogy: Querying is like using filters on a shopping website. Instead of seeing all products, you filter by category, price range, brand, etc., to find exactly what you want.

Basic Queries

Getting All Records

Finding Single Records

When to use what?
  • find() - When you have the ID and it’s okay if the record doesn’t exist
  • findOrFail() - When you have the ID and the record must exist
  • findBy() - When searching by a specific column value
  • first() - When you want the first record from a query

The Query Builder

The query builder lets you chain methods to build complex queries:
How chaining works: Each method returns a query builder object, so you can keep adding more conditions. Think of it like building a sentence: “Get users WHERE active is true AND age is greater than 18, ORDER BY name, LIMIT to 10.”

Where Clauses

Basic Where Conditions

Available Operators

OR Conditions

Where In / Not In

Null Checks

Between Values

Date Queries

whereDate, whereDay, whereMonth, whereYear, and whereTime all work across MySQL, PostgreSQL, and SQLite.

JSON Queries

For databases that support JSON (PostgreSQL, MySQL):

Ordering Results

Limiting and Pagination

Basic Limiting

Built-in Pagination

Aggregates

Get summary information about your data:

Grouping and Having

Joins

Combine data from multiple tables:
When to use joins vs relationships: Use joins when you need specific data from related tables in a single query. Use relationships (covered in the next section) when you want to work with related models as objects.

Raw Queries

Sometimes you need to write custom SQL:
Security Note: Always use parameter binding (?) in raw queries to prevent SQL injection attacks. Never concatenate user input directly into SQL strings.

Advanced Subqueries

Subquery in addSelect

Add a computed column from a subquery without a join:

Order by a subquery

Sort results by a value computed from another table:

Pending Attributes on Scopes

When you use a scoped query to create records, withPendingAttributes() lets the scope automatically set default column values on any model created through it:
You can also call create() on the scoped query:

Column Expressions with F()

Use F() to reference a column’s current value in an update — no raw SQL, no race conditions, no need to fetch the record first:
Available operations: .plus(n), .minus(n), .times(n), .divide(n).
F() generates a safe parameterized expression — it never interpolates values directly into SQL.

Plain Objects with values()

get() always returns model instances. Use values() when you only need the raw data and want to skip model hydration — faster for read-heavy endpoints:

Strict Fetching and Debugging

sole() — exactly one or throw

sole() is like firstOrFail() but also throws if more than one record matches. Use it when your query should always return exactly one row:

tap() — debug without breaking the chain

tap() runs a callback for logging or inspection without affecting the query:

Conditional Queries

Build queries based on conditions:

Exists Queries

Use whereHas / doesntHave to filter by whether a named relationship exists. These build a WHERE EXISTS subquery automatically.
The related model must be registered in ModelRegistry (call static { this.register(); } in its class body) so the ORM can resolve its table name at query-build time.
has(relation, operator?, count?) is the simple form — filter by relation existence with an optional count. Use whereHas when you need to add constraints on the related records themselves.

Raw subquery existence

Query Scopes

Reusable query logic (defined in your model):

Performance Tips

1. Use Specific Selects

2. Use Limits

3. Use Indexes

Make sure your database has indexes on columns you query frequently:

4. Use Eager Loading for Relationships

Common Query Patterns

Search Functionality

Dashboard Statistics

Filtering with Multiple Options

Next Steps

Learn Relationships

Connect different models together

Database Migrations

Set up and modify your database structure