Skip to main content
The general form of that statement is:

WITH clause

The with clauses allow you to give names to subquery which you can then reference. The syntax for a with clause is:
For example, using the nexmark source, you can create datasets for bids and price and then join.

Worked example

Given a bids table: And an auctions table: The following query uses CTEs to join bids with their auction items:
Result: Each bid row is matched to its corresponding auction by joining auction_id to id, producing one output row per bid with the item name attached.

SELECT clause

The select cause is a comma-separated list of expressions, with an optional alias. Column names must be unique.

FROM clause

The FROM clause specifies the primary source of data. It will be either a table name or subquery. The table name can be either a saved source, a table created in the WITH clause or a table created via CREATE TABLE and inserted into. Tables can be given aliases, but will default to their name as the alias for things like joins.

JOIN clause

The JOIN clause allows you to join multiple tables together. See the join documentation for more details.

WHERE clause

The WHERE clause allows you to filter the data with a boolean condition. This predicate is applied to the incoming rows, so cannot include conditions on the resulting columns.

Worked example

Given an events table: The following query filters to only pageview events:
Result: Only rows where event_type = 'pageview' pass the filter. The click and purchase events are excluded.

GROUP BY clause

The GROUP BY clause is used to compute aggregates over some set of fields. All GROUP BY queries will implicitly include a time window, and if the input doesn’t already have a time window, it should be specified as one of the grouping fields. For example,

Worked example

Given a bids table with events arriving over time: The following query counts the number of bids and distinct auctions per 1-minute tumbling window:
Result (assuming all events fall within the same 1-minute window): The tumble(interval '1 minute') creates fixed, non-overlapping 1-minute windows. All rows within each window are aggregated together. See the windows documentation for more on tumbling and other window types.

HAVING clause

The HAVING clause allows filtering on the result of aggregations (as opposed to WHERE, which filters on the inputs to the aggregation). For example:
This query counts pageview events by user, then returns those users with more than 5 pageviews.

Worked example

Given the same events table: The following query counts all events per user, then keeps only users with more than 1 event:
Result:
  • alice has 2 events (pageview + purchase) - included
  • bob has 2 events (click + pageview) - included
  • charlie has 1 event (pageview) - excluded by the HAVING filter

UNNEST operator

The UNNEST operator allows you to unnest arrays into multiple rows. This can be used as a normal scalar function with the following restrictions:
  • It may only appear in the SELECT clause
  • Only one array may be unnested per select statement For example,
which will produce the following output:

Worked example

Given a bids table: The following query unnests a fixed array for each input row:
Result: Each input row is expanded into multiple output rows - one for each element in the unnested array. The other columns are repeated for each expanded row.
Last modified on October 1, 2026