SQL editor
Contents
The SQL editor enables you to directly access all your data in PostHog, from PostHog-specific events
and persons
tables to your external sources, using SQL queries.
SQL commands
You create SQL queries out of a list of commands that shape what data, filters, aggregations, and ordering we want to see.
SQL queries in PostHog don’t require the trailing semicolon (
;
) of traditional SQL queries.
SELECT
Use SELECT
to select data (usually columns, transformations, or aggregations) from one or more tables in the database. You can use arithmetic or functions to modify the selected data.
Common values to select are *
(representing all), event
, timestamp
, properties
, and functions like count()
. You can access properties using dot notation like person.properties.$initial_browser
. These values can be found in the data management properties tab or inside tables in the SQL tab.
Add the DISTINCT
clause to SELECT
commands to keep only unique rows in query results.
FROM
Use FROM
to select the database table to run the queries on. In PostHog, examples include events
, groups
, raw_session_replay_events
, and more listed in the data management database tab.
FROM
also enables you to break down your query into subqueries. This is useful for analyzing multiple groups of data. For example, to get the difference in event count between the last 7 days and the 7 days before that, you can use two subqueries like this:
JOIN
You can query over multiple tables together using the JOIN
command. This combines the tables and returns different records depending on which of the four conditions you use:
INNER JOIN
: Records with matching values in both tables.LEFT JOIN
: All records from the left table and the matched records from the right table.RIGHT JOIN
: All records from the right table and the matched records from the left table.FULL JOIN
: All records matching either the left or right tables.
The command then takes one table before it and another after it and combines them based on the join condition using the ON
keyword. For example, below, the events table is the left table and the persons table is the right table:
This is especially useful when combining PostHog data and an external source. For example, once you set up the Stripe connector, you can query for a count of events from your customers like this:
WHERE
Use WHERE
to filter rows based on specified conditions. These conditions can be:
- Comparison operators like
=
,!=
,<
, or>=
- Logical operators like
AND
,OR
, orNOT
. These are often used to combine multiple conditions. - Functions like
toDate
,today()
- Clauses like
LIKE
,IN
,IS NULL
To have the insight or dashboard date range selector apply to the insight, include {filters}
in query like this:
WHERE
is also useful for querying across multiple tables. For example, if you have the Hubspot connector set up, you can get a count of events for contacts with a query like this:
GROUP BY
Use GROUP BY
to group rows that have the same values in specified columns into summary rows. It is often used in combination with aggregate functions.
ORDER BY
Use ORDER BY
to sort the query results by one or more columns. You can specify order by ascending with ASC
or descending with DESC
.
LIKE
Use LIKE
to search for a specified pattern in a column. This is often done in the WHERE
command. You can also use ILIKE
to make the search case insensitive.
Use the %
sign to represent any set of characters (wildcard). Use the _
sign to define a single character wildcard.
For example, to get all the current URLs that contain the string "docs" you can use:
AS
Use AS
to alias columns or tables with different names. This makes the query and results more readable.
LIMIT
Use LIMIT
to restrict the number of rows returned by the query. It specifies the maximum number of rows the query should retrieve. By default, PostHog sets it at 100
.
To paginate results, you can use the OFFSET
command. For example, to get the 101-150th rows, you can use it like this:
Note: SQL insights default to a
LIMIT 100
. If you're adding the insight to a dashboard or using longer date ranges, consider explicitly increasing the limit to ensure all relevant data is shown.
HAVING
Use HAVING
with the GROUP BY
command to filter the results based on aggregate function values. While WHERE
filters rows before grouping, HAVING
filters grouped results after aggregation.
WITH
Use WITH
to define a temporary result set that you can reference within a larger query. It helps break down complex queries into smaller parts. You can think of it as a function that returns a temporary table similar to using a subquery in a FROM
command. The difference is that we query WITH
subqueries each time they are used, potentially leading to slower queries.
WINDOW
Use WINDOW
to query data across a set of rows related to the current row without grouping the rows in the output like aggregates do. This is useful for complex queries that need row-level detail while also aggregating data from a set of rows.
A window function contains multiple parts:
PARTITION BY
: Divides the rows into partitions which the function then applies to. Each partition is processed separately.ORDER BY
: Sorts rows within each partition.Frame Specification: Defines the subset of rows to include in the window such as
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
.
It is useful for analysis like running totals, moving averages, ranking, and percentiles. For example, to get a running total of pageviews, you can:
CASE
Use CASE
within the SELECT
command to implement conditional logic within your SQL queries. It allows you to execute different SQL expressions based on conditions. It is similar to if/else statements in programming.
For example, to group properties.$os
values in mobile
, desktop
, and other
, you can use:
Comments
Use two dashes (--
) to write comments.