Query modes
Every widget runs a ClickHouse query to fetch its data. Vortex offers two ways to write that query: simple mode and full query mode.
Use simple mode whenever possible. It is shorter, less error-prone, and the widget editor validates both fields independently. Full query mode exists only for cases that simple mode cannot express.
Simple mode
Section titled “Simple mode”Simple mode splits the query into two fields:
| Field | What to write | Example |
|---|---|---|
| Select | The SELECT clause — column expressions only, no SELECT keyword | platform, count() AS count |
| Filters | Everything that comes after FROM — WHERE, GROUP BY, ORDER BY, HAVING, LIMIT | WHERE name = 'app_started' GROUP BY platform ORDER BY count DESC |
The FROM clause is injected automatically between the two fields — pointing to a view of your project’s events already scoped to the dashboard time range and any active global filters. You never write it yourself.
Example
Section titled “Example”Select
platform, count() AS countFilters
WHERE name = 'app_started'GROUP BY platformORDER BY count DESCSELECT platform, count() AS countFROM {table}WHERE name = 'app_started'GROUP BY platformORDER BY count DESCSimple mode covers the vast majority of widget queries: aggregations, GROUP BY, ORDER BY, LIMIT, and any WHERE filter.
Full query mode
Section titled “Full query mode”Full query mode lets you write a complete SQL statement. Use it only when simple mode cannot express the query — typically when you need subqueries or CTEs.
In full query mode, write the entire SELECT … FROM … WHERE … statement. Use {table} as the table reference — it is a macro the backend resolves at runtime into a pre-filtered view of your project’s events, already scoped to the dashboard time range and any active global filters.
SELECT round(avg(duration), 1) AS valueFROM ( SELECT session_id, dateDiff('minute', min(timestamp), max(timestamp)) AS duration FROM {table} WHERE name = 'app_started' GROUP BY session_id)When full query is necessary
Section titled “When full query is necessary”| Situation | Why simple mode doesn’t work |
|---|---|
Subquery in FROM | Simple mode’s filters field only covers clauses after a single FROM |
CTE (WITH … AS (…)) | Requires writing WITH before SELECT |
| Window functions that reference the outer query | Needs a wrapping subquery |
If you are unsure which mode to use, try simple mode first. If the query requires a subquery or CTE, switch to full query mode.
Side-by-side comparison
Section titled “Side-by-side comparison”| Simple mode | Full query mode | |
|---|---|---|
| Fields | select + filters | full_query |
| FROM clause | Added automatically | You write it (FROM {table}) |
| Subqueries / CTEs | Not supported | Supported |
| When to use | Almost always | Only when subqueries or CTEs are needed |
Prohibited keywords
Section titled “Prohibited keywords”Regardless of mode, these SQL keywords are never allowed and will be rejected:
DROP, ALTER, INSERT, UPDATE, DELETE, TRUNCATE, CREATE, RENAME,
UNION, JOIN, INTO OUTFILE, LOAD DATA, SET, KILL, SHOW, DESCRIBE,
EXPLAIN, USE, GRANT, REVOKE
Only safe SELECT queries are permitted.