Skip to content

Joins

join() adds a JOIN to the plan. MountSQLI supports inner, left, and right joins with explicit column pairs.

const rows = await db
.from(posts)
.join("users", "inner", "authorId", "id")
.all();

This compiles to:

SELECT * FROM "posts" INNER JOIN "users" ON "posts"."authorId" = "users"."id"
db.from(posts).join("users", "left", "authorId", "id").all();
db.from(posts).join("users", "right", "authorId", "id").all();

Pass a fifth argument to alias the joined table:

db.from(posts).join("users", "inner", "authorId", "id", "u").all();

The result is a union of both row shapes. Use select() to keep only the columns you need:

db.from(posts)
.join("users", "inner", "authorId", "id")
.select("posts.title", "users.email")
.all();

List posts with their author’s email:

export async function postsWithAuthors() {
return db
.from(posts)
.join("users", "inner", "authorId", "id")
.select("posts.title", "users.email")
.orderBy("posts.createdAt", "desc")
.all();
}
  • Pick the join type that matches your nullability need (left = keep left rows).
  • Alias when joining the same table twice.
  • Select explicit columns to avoid column-name collisions.
  • Using inner when you need orphaned left rows — they disappear.
  • Forgetting to qualify columns with the table name in select().
  • SelectfindMany({ with }) for nesting.
  • Filtering — filter on joined columns.