dDatahopdocs
Product analytics

SQL Editor

Ask anything of your data in SQL, save queries as reusable tables, and chart them on dashboards.

When a question doesn't fit a trend, funnel or retention chart, write SQL. SQL Editor in the sidebar has everything you can query on the left, the editor on top and the result below.

SELECT person.properties.plan AS plan,
  uniq(person_id) AS weekly_users
FROM events
WHERE timestamp > now() - INTERVAL 7 DAY
GROUP BY plan
ORDER BY weekly_users DESC

Press ⌘ ↵ (Ctrl ↵ on Windows and Linux) to run it.

The explorer

The panel on the left lists everything you can query:

  • Tables, with row counts. Open one to see its columns and their types. events also lists every property as properties.<key> (with how many events carry it) and its event names; persons lists person properties, and groups lists each group type's properties.
  • Views: your saved queries, which work as tables.
  • Computed properties: person properties that saved queries write.
  • Cohorts, with their size.

Double-click a name, press ↵, or drag it into the editor to insert it. Hover a row for its description, and use ▶ Preview to see its first 100 rows or most common values. Preview runs in the editor when it's empty, and in a new tab otherwise, so you don't lose your work. Right-click a row for everything else: copy its name, insert a cohort as inCohort(person_id, 3), or open, rename or delete a view.

Search finds tables, columns, properties, views and cohorts. The filter button hides built-in $ properties, system tables or empty sections. Use the arrow keys to move through the list. Drag the panel's edge to resize it, or collapse it with ‹.

Tables

TableOne row per
eventsEvent your apps sent
personsPerson
sessionsVisit: start and end, duration, pageviews, entry and exit page, source, bounce
groupsCompany, team or other group
person_overridesMerged identity: an old person id and the person it now belongs to
cohort_static_membersMember of a static or SQL cohort (use inCohort() for any cohort)

Times are in your project's timezone. person_id already joins up the ids of someone who used several devices before signing in, so uniq(person_id) counts real people.

Shorthands

WriteTo get
properties.planA property, as text. Use properties['my key'] for keys with spaces.
toFloat64OrNull(properties.amount)A property as a number
person.properties.emailOn events: the property of the person who sent the event
inCohort(person_id, 3)Whether the person is in cohort 3

The editor completes tables, views, columns, property keys and cohorts as you type. After properties. it suggests the keys of the table you select from.

Saved queries are tables

Save a query and give it a name like paying_users. From then on it works as a table in any other query:

SELECT count() FROM paying_users
WHERE upgraded_at > now() - INTERVAL 14 DAY

That's how you build your own definitions, like "active account", "first order" or "power user", once, without setting anything up elsewhere. Saved queries can build on each other. Datahop checks a query runs before saving it, and won't delete one that another saved query or a cohort still reads from.

Charts and dashboards

Results show as a table, or switch to Line, Bar or Number and pick the columns to plot. Saving keeps the chart. ⋯ → Create alert watches one of its numbers (see Alerts). ⋯ → Add to dashboard puts it on any dashboard, including public ones: people with the link see the result, never the SQL. A dashboard's date range doesn't apply to SQL cards, because the query sets its own.

Copy or download any result as CSV from the result bar.

Cohorts and person properties from SQL

A saved query with a person_id column can feed the rest of Datahop. Open it and choose ⋯ → Use with people:

  • Create cohort makes a cohort of everyone the query returns.
  • Set person properties writes every other column onto those people. With the query below, each customer gets orders and lifetime_value, which you can then use to target a feature flag, segment an experiment or break down a chart.
SELECT person_id,
  count() AS orders,
  round(sum(toFloat64OrNull(properties.amount)), 2) AS lifetime_value
FROM events
WHERE event = 'order_completed'
GROUP BY person_id

Both recalculate every hour and whenever you change the query. People who drop out of the result lose the cohort membership or the properties. Datahop manages these property names, so don't also set them from your app. Turning Set person properties off removes them.

Ask AI

Ask AI turns a question into SQL that runs against your real events and properties, and explains what it returns. When a query fails, Fix with AI rewrites it using the error. Both need the AI assistant switched on for your workspace.

Agents

Agents use the same SQL. Over MCP, sql_schema lists the tables, saved queries, events, properties and cohorts; sql runs a query; and save_query saves one as a table, so an agent can define active_accounts once and every person and agent can use it. See the tool reference.

Agent-first

Hand this to your agent to connect it, then ask it questions in plain language. It writes and saves the SQL.

Limits

One read-only SELECT per run, up to 20 seconds and 10,000 rows. Aggregate in SQL or add a LIMIT for bigger results.

On this page