Select Overview
Learn the high-level select helpers for reading lists, single rows, scalar values, and map results.
The select helpers are the most common way to read data with the shared db package.
They are designed for everyday queries where you already have:
- a
context.Context - a
db.Conn - a SQL or CQL query string
- optional query arguments
The select helpers create a db.Query internally and execute it through the active driver.
Available Helpers
| Helper | Result | Use case |
|---|---|---|
db.List[T] | []T | Read multiple rows into a typed slice |
db.Get[T] | (T, bool, error) | Read zero or one row into a typed value |
db.Value[T] | (T, bool, error) | Read one scalar value |
db.Maps | []map[string]any | Read rows as dynamic maps |
These helpers are the highest-level read API.
For lower-level usage with db.Query, use the Query Objects helpers.
For SQL loaded from model files, use the Dialect SQL helpers.
List
Use db.List when the query returns multiple rows.
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)
if err != nil {
return nil, err
}Example query for MySQL:
const selectUsersQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT ?
`Example query for PostgreSQL:
const selectUsersQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT $1
`Example query for Scylla:
const selectPostsByUserQuery = `
SELECT *
FROM posts_by_user
WHERE user_id = ?
LIMIT ?
`db.List scans all returned rows into []T.
Get
Use db.Get when the query should return zero or one row.
user, found, err := db.Get[User](ctx, conn, selectUserQuery, id)
if err != nil {
return User{}, false, err
}
if !found {
return User{}, false, nil
}Example query for MySQL:
const selectUserQuery = `
SELECT *
FROM users
WHERE id = ?
LIMIT 1
`Example query for PostgreSQL:
const selectUserQuery = `
SELECT *
FROM users
WHERE id = $1
LIMIT 1
`Example query for Scylla:
const selectUserByEmailQuery = `
SELECT *
FROM users_by_email
WHERE email = ?
LIMIT 1
`db.Get returns:
value, found, errfound is false when the query returns no rows.
Value
Use db.Value when the query returns one scalar value.
total, found, err := db.Value[int64](ctx, conn, countUsersQuery)
if err != nil {
return 0, false, err
}
if !found {
return 0, false, nil
}Example query:
const countUsersQuery = `
SELECT COUNT(*)
FROM users
`Scylla example:
const countPostsByUserQuery = `
SELECT COUNT(*)
FROM posts_by_user
WHERE user_id = ?
`db.Value expects exactly one selected column.
It is useful for:
- counts
- IDs returned from
RETURNING - flags
- aggregate values
- simple lookups
Maps
Use db.Maps when you want rows as dynamic map[string]any values.
rows, err := db.Maps(ctx, conn, selectUserMapsQuery, 10)
if err != nil {
return nil, err
}Example query for MySQL:
const selectUserMapsQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT ?
`Example query for PostgreSQL:
const selectUserMapsQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT $1
`Example query for Scylla:
const selectPostMapsByUserQuery = `
SELECT *
FROM posts_by_user
WHERE user_id = ?
LIMIT ?
`db.Maps is useful for:
- dynamic results
- admin screens
- reports
- debugging
- generic tooling
For stable application models, prefer db.List or db.Get.
Placeholder Differences
The Go helper API is the same across drivers, but SQL placeholders are still driver-specific.
| Driver | Placeholder style |
|---|---|
| MySQL | ? |
| Postgres | $1, $2, $3 |
| Scylla | ? |
Example MySQL call:
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)Example PostgreSQL call:
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)The Go code looks the same, but the query string uses the placeholder style required by the selected driver.
Choosing the Right Helper
| Need | Use |
|---|---|
| Multiple typed rows | db.List[T] |
| Zero or one typed row | db.Get[T] |
| One scalar value | db.Value[T] |
| Dynamic map rows | db.Maps |
Select Helpers vs Query Objects
The select helpers accept a raw query string and arguments directly.
users, err := db.List[User](ctx, conn, query, args...)Internally, they create a db.Query for you.
Use Query Objects when you want to build the query first:
q, err := db.Raw(query, args...)
if err != nil {
return nil, err
}
users, err := db.ListQuery[User](ctx, conn, q)Select Helpers vs Dialect SQL
Use select helpers when the query is written directly in Go code.
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)Use Dialect SQL helpers when the query comes from a loaded SQL model file.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)Dialect SQL is useful when the same application can run with MySQL, PostgreSQL, or Scylla and each driver needs its own query text.
Recommended Usage
Start with the select helpers.
Use:
db.List[T]for list endpoints.
Use:
db.Get[T]for lookup endpoints.
Use:
db.Value[T]for counts, aggregate values, or returned IDs.
Use:
db.Mapswhen the result shape is dynamic.
Continue with the dedicated pages for each helper to see complete examples.