Skip to main content

Query Building

All queries are built using type-safe column references. The compiler catches typos and type mismatches.

SELECT

// Select all columns
query := Users.SelectAll()

// Select specific columns
query := Users.Select(Users.ID, Users.Email)

// With conditions
query := Users.SelectAll().
Where(Users.Email.Eq("john@example.com")).
Where(Users.IsActive.Eq(true)).
OrderByDESC(Users.CreatedAt).
Limit(10).
Offset(20)

Available Methods

MethodSQL
.Fields(cols...)SELECT specific columns
.Distinct()SELECT DISTINCT
.Where(clause...)WHERE
.GroupBy(cols...)GROUP BY
.Having(clause...)HAVING
.OrderByASC(cols...)ORDER BY ... ASC
.OrderByDESC(cols...)ORDER BY ... DESC
.OrderByRaw(sql...)ORDER BY (raw)
.Limit(n)LIMIT
.Offset(n)OFFSET
.ForUpdate()FOR UPDATE

Joins

query := Users.SelectAll().
InnerJoin(Orders.Table, "o",
Users.ID.EqCol(Orders.UserID),
).
LeftJoin(Profiles.Table, "p",
Users.ID.EqCol(Profiles.UserID),
)

INSERT

// Single row
query := Users.Insert().
Columns(Users.Email, Users.Name).
Values("john@example.com", "John Doe").
Returning(Users.ID)

// Multiple rows
query := Users.Insert().
Columns(Users.Email, Users.Name).
Values("john@example.com", "John").
Values("jane@example.com", "Jane").
Returning(Users.ID)

UPDATE

query := Users.Update().
Set(Users.Name.Set("Jane Smith")).
Set(Users.IsActive.Set(true)).
Where(Users.ID.Eq(1)).
Returning(Users.ID, Users.Name)

DELETE

query := Users.Delete().
Where(Users.IsActive.Eq(false))

Where Clause Operators

Comparison

Users.ID.Eq(1)         // = 1
Users.ID.Neq(1) // != 1
Users.ID.Gt(1) // > 1
Users.ID.Gte(1) // >= 1
Users.ID.Lt(10) // < 10
Users.ID.Lte(10) // <= 10

IN / NOT IN

Users.ID.In(1, 2, 3)       // IN (1, 2, 3)
Users.ID.NotIn(1, 2, 3) // NOT IN (1, 2, 3)
Users.ID.InOf(subquery) // IN (SELECT ...)

BETWEEN

Users.ID.Between(1, 100)      // BETWEEN 1 AND 100
Users.ID.NotBetween(1, 100) // NOT BETWEEN 1 AND 100

LIKE / ILIKE

Users.Email.Like("%@example.com")    // LIKE
Users.Email.ILike("john%") // ILIKE (case-insensitive)
Users.Email.NotLike("%@spam.com") // NOT LIKE

NULL Checks

Users.Bio.IsNull()       // IS NULL
Users.Bio.IsNotNull() // IS NOT NULL

Array Operators (PostgreSQL)

Users.Tags.ARRAYContains("go", "rust")     // @> ARRAY[...]
Users.Tags.ARRAYContainedBy("go") // <@ ARRAY[...]
Users.Tags.ARRAYOverlap("go", "rust") // && ARRAY[...]

JSON Operators

Users.Data.JSONContains(`{"role":"admin"}`)   // @> '...'
Users.Data.JSONHasKey("role") // ? 'role'
Users.Data.JSONHasAnyKey("role", "name") // ?| ARRAY[...]
Users.Data.JSONHasAllKeys("role", "name") // ?& ARRAY[...]

Logical Operators

// AND (multiple Where calls are AND'd)
Users.SelectAll().
Where(Users.IsActive.Eq(true)).
Where(Users.Email.Like("%@example.com"))

// OR
Users.SelectAll().
Where(Users.Or(
Users.Email.Eq("admin@example.com"),
Users.IsActive.Eq(true),
))

// Subqueries (non-correlated)
Users.ID.EqOf(subquery) // = (SELECT ...)
Users.ID.InOf(subquery) // IN (SELECT ...)
Users.ID.AnyOf(subquery) // = ANY(SELECT ...)

// EXISTS (non-correlated)
Users.Table.ExistsOf(subquery) // EXISTS (SELECT ...)
Users.Table.NotExistsOf(subquery) // NOT EXISTS (SELECT ...)

// Raw SQL
Users.Email.EqRaw("current_user")
Users.Table.Raw("age > $1", 18)

Correlated Subqueries

Use Table.Ref(column) to reference a column from an outer query inside a subquery. This enables correlated EXISTS, IN, and other subquery patterns where the inner query depends on the outer row.

// Find active users who have at least one paid order:
//
// SELECT * FROM users
// WHERE users.deleted_at IS NULL
// AND EXISTS (
// SELECT 1 FROM orders
// WHERE orders.user_id = users.id
// AND orders.status = $1
// )
subquery := Orders.Select1().Where(
Orders.UserID.EqRef(Users.Table.Ref(UserColumnID)), // orders.user_id = users.id
Orders.Status.Eq("PAID"),
)

query := Users.SelectAll().Where(
Users.DeletedAt.IsNull(),
Users.Table.ExistsOf(subquery),
)

Ref returns a column reference that writes table.column directly into SQL without a parameter placeholder. It works with any comparison method:

Col.EqRef(OtherTable.Ref(col))   // col = other_table.col
Col.NeqRef(OtherTable.Ref(col)) // col != other_table.col