Skip to main content

SELECT

Retrieves rows from one or more tables. SELECT is the primary way to read data in Turso and supports filtering, joining, aggregation, sorting, subqueries, and set operations.

Syntax

Parameters

Basic Queries

Selecting Columns

Column and Table Aliases

Use AS to assign aliases to columns or tables. The AS keyword is optional for column aliases.

FROM Clause

The FROM clause specifies the source tables for the query. It accepts table names, aliased tables, subqueries, and join expressions.

WHERE Clause

Filters rows based on a condition. Only rows where the expression evaluates to true are included in the result.

Comparison Operators

Logical Operators

Combine conditions with AND, OR, and NOT.

Pattern Matching

Range and Membership Tests

NULL Tests

CASE Expressions

JOIN Clause

Combines rows from two or more tables based on a related column.

Supported Join Types

INNER JOIN

Returns only rows where the join condition is satisfied in both tables.

LEFT OUTER JOIN

Returns all rows from the left table. When no matching row exists in the right table, the right-side columns contain NULL.

FULL OUTER JOIN

Returns all rows from both tables. When a row in either table has no match in the other table, the missing side’s columns contain NULL.

NATURAL JOIN

Automatically joins on all columns with identical names in both tables. Equivalent to JOIN … USING with every shared column name.

JOIN … USING

Joins on the specified column that must exist in both tables. The shared column appears only once in the result.

Multi-Table Joins

GROUP BY and HAVING

GROUP BY

Groups rows that share the same values in the specified columns. Typically used with aggregate functions.
Aggregate functions that can be used with GROUP BY:

HAVING

Filters groups after aggregation. WHERE filters individual rows before grouping; HAVING filters groups after.

GROUP BY with Expressions

DISTINCT

Removes duplicate rows from the result set.
DISTINCT applies to the entire result row, not to a single column. Two rows are considered duplicates only if every column value is identical.

ORDER BY

Sorts the result set. Without ORDER BY, the row order is unspecified.

NULLS FIRST / NULLS LAST

Controls where NULL values appear in the sorted result.

LIMIT and OFFSET

Restricts the number of rows returned and optionally skips a number of rows.
Always use ORDER BY with LIMIT and OFFSET. Without ORDER BY, the set of rows skipped or returned is arbitrary.

Subqueries

A subquery is a SELECT statement nested inside another query.

Scalar Subqueries

Returns a single value. Can be used anywhere an expression is expected.

Subqueries with IN

Tests whether a value matches any row returned by the subquery.

Subqueries with EXISTS

Tests whether the subquery returns at least one row. The actual values are ignored.

Subqueries in FROM

A subquery in the FROM clause acts as a derived table and must have an alias.

Common Table Expressions (CTE)

A WITH clause defines one or more temporary named result sets that exist for the duration of the query.

Multiple CTEs

CTEs in Turso are SELECT-only. RECURSIVE CTEs and the MATERIALIZED/NOT MATERIALIZED hints are not supported.

Window Functions

A window function performs a calculation across a set of rows related to the current row, without collapsing them into a single output row.

Named Windows

Use the WINDOW clause to define a reusable window definition.

Window Clause Syntax

Standard aggregate functions (SUM, AVG, COUNT, MIN, MAX, TOTAL, GROUP_CONCAT) can all be used as window functions.
Window functions in Turso use the default frame definition (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW). Custom frame specifications (ROWS, RANGE, GROUPS with explicit bounds) are not supported. The row_number() ranking function and the FILTER (WHERE ...) clause are supported; other ranking and navigation functions (rank, dense_rank, lag, lead, and so on) are not yet available.

Set Operations

Combine the results of two or more SELECT statements. All set operations require the same number of columns in each SELECT, with compatible types.

UNION ALL

When duplicates are acceptable, UNION ALL is faster because it skips the deduplication step.

Set Operations with ORDER BY

ORDER BY applies to the entire combined result set and must appear after the last SELECT.

Examples

Paginated Report with Aggregation

CTE with Filtered Join

Subquery with EXISTS and LEFT JOIN

See Also