with block and CTE rules, see Supported SQL — CTE and WITH syntax.
Why Use CTEs
Consider an app where users belong to organizations. Several tables need to filter by the user’s organizations:Defining CTEs
Define CTEs in awith block inside a stream. Each CTE has a name and a SELECT query:
Using CTEs in Queries
Once defined in a stream’swith block, use the CTE name in that stream’s query or queries. You can use it like a subquery or join it as if it were a table.
Short-hand syntax (when the CTE has exactly one column):
IN cte_name is equivalent to IN (SELECT * FROM cte_name). If the CTE has more than one column, this form is an error; use explicit subquery or join syntax instead.
Explicit subquery syntax (when you need to select specific columns):
Combining with Multiple Queries
CTEs work well with thequeries feature (multiple queries per stream). This lets you share the CTE and keep all query results in one stream: the client only needs to manage one subscription instead of multiple.
Complete Example
A full configuration using CTEs. Each stream that needs shared logic defines its ownwith block:
Limitations
The following rules apply to CTEs. For the full syntax reference, see Supported SQL — CTE and WITH syntax. Sync Streams do not support global CTEs. Use awith block only inside a stream. To reuse logic across streams, define the same CTE (or equivalent subquery) in each stream that needs it, or combine streams using multiple queries per stream so one stream can share a single CTE across queries.
CTEs cannot reference other CTEs. Each CTE must be self-contained:
IN cte_name works only when the CTE has exactly one column. If the CTE has multiple columns, use explicit subquery syntax or join the CTE as a table.
CTE names take precedence over table/collection names. If you define a CTE with the same name as a database table/collection, the CTE will be used. Choose distinct names to avoid confusion.