Query structure

A FeatureQL query defines features, selects which ones to return, and binds concrete values to their inputs. You can then filter, sort, and paginate the results — just like SQL.

Anatomy of a query

[WITH
    feature_name := expression, -- Feature definition
    ...
]
SELECT
    feature_name, -- Feature to evaluate and return
    ...
[FROM namespace, ...]
[FOR feature_name := BIND(), ...] -- Bind values to inputs
[WHERE boolean_expression] -- Filter results
[ORDER BY expression [ASC|DESC] [NULLS FIRST|LAST], ...] -- Sort results
[LIMIT count [OFFSET count]] -- Paginate results
sql

Each clause has a specific role:

ClauseDescription
WITHDefines features locally, on top of what already exists in the registry.
SELECTLists the features to evaluate and return.
FROMDefines one or more namespaces to pull features from.
FORBinds concrete values to the query's inputs. Without binding, a query with features depending on INPUT() features won't execute.
WHEREFilters the result rows. You can reference any feature at the same granularity as the query.
ORDER BYSorts the results. Supports ASC/DESC and NULLS FIRST/NULLS LAST.
LIMIT
OFFSET
Controls pagination.

Note: GROUP BY and UNNEST are supported for analytics queries. See Grouping and unnesting for details.

Intermediate features with WITH

Complex queries often need intermediate calculations that shouldn't appear in the output. The WITH clause defines features that are available for computation but excluded from the result:

FeatureQL
WITH
    1 AS NUMBER1,            -- Intermediate calculation
    2 AS NUMBER2,            -- Intermediate calculation
SELECT
    NUMBER1,                        -- Exposed in results
    NUMBER1 + NUMBER2 AS NUMBER3    -- Exposed in results
;
Result
NUMBER1 BIGINTNUMBER3 BIGINT
13

NUMBER2 is used to compute NUMBER3 but doesn't appear in the output. This keeps query results focused on what consumers actually need.

Functions that must live in WITH

Some functions produce internal values that can't be returned directly:

Function typeWhy it can't be returnedWhat to return instead
INPUT()Declares a parameter placeholderThe bound values via BIND_XXX()
ENTITY()Declares an entityThe bound values of the INPUT() referencing the entity
SOURCE_XXX()Declares a connectionThe EXTERNAL_XXX() that uses the source
UDF()
MACRO()
Declares a functionThe function applied to concrete parameters

Example

This example brings it all together: it defines an input with a data source, computes a derived feature, binds values, filters, sorts, and paginates.

FeatureQL
WITH
    -- Input definitions
    CUSTOMER_ID := INPUT(BIGINT),
    -- Mapping to data source
    DIM_CUSTOMERS := INLINE_COLUMNS(
        customer_id BIGINT BIND TO CUSTOMER_ID,
        name VARCHAR
        FROM CSV(
            customer_id,name
            101,Alice
            102,Bob
            103,Charly
            104,Daniel
            105,Elody
            106,Francis
            107,George
            108,Henry
            109,Isaac
            110,Jack
        )
    ),
    -- Define pure transformations
    NAME := DIM_CUSTOMERS[name],
    NAME_LENGTH := LENGTH(NAME)
SELECT
    -- Features to evaluate and return
    CUSTOMER_ID,
    NAME,
    NAME_LENGTH
FOR
    CUSTOMER_ID := BIND_VALUES(SEQUENCE(101, 106)),
WHERE NAME < 'Henry'
ORDER BY NAME DESC
LIMIT 3 OFFSET 1
Result
CUSTOMER_ID BIGINTNAME VARCHARNAME_LENGTH BIGINT
105Elody5
104Daniel6
103Charly6

Last update at: 2026/03/18 16:18:57
Last updated: 2026-03-18 16:19:34