by Holistics
Try with anfra

AQL · Analytics Query Language

The query language built for AI reasoning

AQL is the high-level query language for analytics. Expressive enough for an AI agent to answer any question, concise enough for a human to trust the answer.

What’s our refund rate?

AQLHolistics AI3 metrics · composed
metric revenue =
  sum(order_items.quantity * products.price)

metric refunded_revenue =
  revenue | where(orders.status == 'refunded')

metric refund_rate =
  safe_divide(refunded_revenue, revenue)
  • compiles to your warehouse’s native SQL · see how

A query language that thinks in metrics

AQL works at the level of metrics, not tables. You define a metric once on your semantic model, then ask for it by name, and AQL compiles that to native SQL.

AQLDefine oncein your semantic model
metric revenue =
  sum(order_items.quantity * products.price)
AQLAsk by namerevenue by country
explore {
  dimensions { customers.country }
  measures   { revenue }
}
SQLAQL compiles tonative SQL
SELECT   c.country,
         SUM(oi.quantity * p.price) AS revenue
FROM     order_items oi
JOIN     products  p ON oi.product_id = p.id
JOIN     orders    o ON oi.order_id   = o.id
JOIN     customers c ON o.customer_id = c.id
GROUP BY c.country
ORDER BY revenue DESC
“I’d score AQL a 9 or 10. It’s up there with the best tools I’ve used. We can now define metrics based on other metrics, stacking them on top of each other.”
IanBI Engineer, DNSFilter · 9–10 · AQL, scored by a BI engineer

Built like a language, not glued together from SQL strings

Most semantic layers store metrics as SQL strings, so composition breaks the moment one metric builds on another. AQL makes each metric a real object you compose like functions, then compiles to native SQL.

90+ prebuilt functions

The CTE-and-window gymnastics SQL forces on you are single functions here.

percent_of_totalrunning_totalrelative_periodof_allrank+ 80 more

Composable

Define a metric once, and others build on it by reference. Metrics compose like functions, instead of repeating each other’s SQL.

Semantic-aware

AQL runs on your semantic model, so queries reference your defined metrics, dimensions, and relationships by name, not raw schema.

No black box

AQL is a compile step, not a runtime. It outputs standard SQL that runs natively in your warehouse, with no proprietary engine in between.

Database-agnostic

Write once. The compiler speaks the dialect.

PostgresRedshiftBigQuerySnowflakeDatabricksSQL ServerClickHouse

Typed, with IDE feedback

A strong type system validates queries as you write. Errors surface in the IDE, not in production dashboards.

The AI does the thinking. The compiler does the SQL.

Most natural-language tools translate your question straight into SQL. Holistics adds an intermediary step. The AI first writes concise, high-level AQL, which a compiler then turns into your warehouse’s SQL.

Natural languageuser input

In each region, what’s the average revenue of the top 5 countries by users?

AI · generates
AQL6 lines · human-readable
metric count_users = count(users.id)
dimensions { region: country.region }
measures {
  avg_revenue:
    top(5, countries.id, by: count_users) | avg(revenue)
}
Compiler · guarantees
SQL55 lines · auto-generated
WITH "aql__t3" AS (
  SELECT "ecommerce_countries"."continent_name"
    AS "ecommerce_countries→continent_name",
    "ecommerce_countries"."name" AS "name",
    COUNT("ecommerce_users"."id") AS
    "count_ecommerce_users→id"
  FROM "ecommerce"."users" "ecommerce_users"
  JOIN "ecommerce"."countries" …
  • no SQL gymnastics

Verifiable in a few readable lines

The answer comes back as a few lines of compact, high-level logic instead of pages of SQL. It’s small enough to read, comprehend, and verify yourself.

Reliable, without SQL gymnastics

Working in a high-level language, the AI never sweats database-specific syntax or SQL gymnastics for common analytics, so it’s far more accurate than a model writing raw SQL directly.

Governed by your semantic layer

AQL works directly with your semantic layer, so generated logic always uses the correct metric and dimension definitions, and clears access-control checks before it serves an end user.

Capable of the hard questions

Composability and 90+ pre-built analytical functions let it handle far more complex use cases, the long-tail questions that direct SQL generation stumbles on.

The questions that break other tools are one-liners

Period comparisons, cohorts, percent-of-total, nested aggregation: the analytics that mean a new dataset or a custom SQL block almost everywhere else. With AQL, each one is a single composable expression.

“How does revenue compare to last year?”

AQLHolistics AI
metric revenue_ly =
  revenue | relative_period(-1 year)

metric yoy_change =
  safe_divide(revenue - revenue_ly, revenue_ly)
  • reuses endorsed metric · revenue
  • read it, confirm it, run it
SQLwhat text-to-SQL hands you14 lines to audit
WITH monthly AS (
  SELECT DATE_TRUNC('month', created_at) AS month,
         SUM(amount) AS revenue
  FROM orders
  GROUP BY 1
)
SELECT
  curr.month,
  curr.revenue,
  (curr.revenue - prev.revenue) * 100.0
    / prev.revenue AS yoy_change
FROM monthly curr
LEFT JOIN monthly prev
  ON curr.month = prev.month + INTERVAL '1 year'
“AQL lets me create a cohort view I couldn’t do before. Every time I wanted a different type of cohort, I had to go back to the model and add to it. Now I can just do it. A dynamic, flexible cohort viz, for a retention person, is really powerful for understanding the drivers behind the successful cohorts.”
Alex HancockDirector, Data / Digital / Loyalty, Pinter · On cohort analysis

Define once. Compose forever.

A metric in AQL is a real semantic object, not a SQL string, so the AI builds on it like code, instead of pasting SQL together.

Metrics are first-class objects

Semantic-aware: it knows your models and relationships, so the join resolves itself. There’s no SQL text to copy.

metric revenue =
  sum(order_items.quantity
      * products.price)

Real composition, not string concatenation

Each metric builds on the one before by reference, like functions. A string-based tool would re-embed all of revenue’s SQL here. AQL never does.

metric refunded_revenue =
  revenue | where(orders.status == 'refunded')

metric refund_rate =
  safe_divide(refunded_revenue, revenue)

Every answer traces back to definitions you already governed

The AI reuses your team’s endorsed metrics and composes new ones from existing definitions. It doesn’t reinvent “revenue” from raw tables, and access controls in the semantic layer apply automatically.

From catalog · Endorsed
weekly_revenuesum(orders.amount) by week

Lineage

orders.amlregions.aml
weekly_revenue
12 dashboardsrevenue report

Catalog status

  • weekly_revenueEndorsed
  • regional_revenueEndorsed
  • ai_calc_revenue_v2Blocked

“Isn’t this just another proprietary language?”

Am I locked in?

AQL compiles to native SQL you can inspect on every query. Nothing is hidden. Your definitions are plain-text code in Git, not rows in a vendor database. If you leave, you leave with readable logic.

Why not just SQL?

AQL is a complement, not a replacement. SQL is great at pipelines and ad-hoc exploration, but it has no native way to define a metric once and compose it. AQL covers exactly that gap. When you need raw SQL, passthrough functions (sql_number, agg_text, …) are the escape hatch.

What about the learning curve?

AQL is designed for agents to write and humans to read. The AI writes most of it; your job is to read a few lines and confirm it understood the question, and because the logic is high-level, that read is fast. When you do want to write it yourself, anyone who reads SQL picks it up from the 30-minute guided tour.

“The AI does far more than just fetch answers. It understands the context and generates working solutions, even for edge cases.”
Guido StarkHead of Data, World Vision

In production across hundreds of enterprises

Go deeper: the functions cheatsheet, learn AQL in 30 minutes, and the AML modeling language