Typed CRUD

Select, filter, order, and limit

Build a bounded query for one user’s newest notes and inspect its result type and generated SQL.

8 minute lesson

~~~

A useful collection query needs a filter, stable order, and limit. Returning every row is not a harmless default.

Use operators such as eq() instead of writing condition strings. Select only the columns the caller needs, order newest first, and add the ID as a tie-breaker when timestamps can match.

import { and, desc, eq, isNull } from 'drizzle-orm'

const rows = await db
  .select({ id: notes.id, title: notes.title })
  .from(notes)
  .where(and(eq(notes.authorId, userId), isNull(notes.archivedAt)))
  .orderBy(desc(notes.createdAt), desc(notes.id))
  .limit(20)

Use isNull() for null checks rather than copying = NULL SQL. SQL null has three-valued logic, so ordinary equality is not the right comparison.

The selected object shape becomes the result type. This is useful for privacy too: if a list does not need note bodies, do not select and move them through the application.

Seed 25 notes with repeated timestamps, then request the first two pages using a bounded limit. Save the generated SQL and prove the order stays deterministic across repeated runs.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →