ClickHouse query editor

This document explains how to use the ClickHouse query editor to build and run queries. You can access the query editor from Explore to run ad hoc queries, or when you add or edit a panel and select the ClickHouse data source.

Before you begin

Query editor elements

The query editor appears in Explore when you select the ClickHouse data source, or when you add or edit a panel and select ClickHouse. It includes the following elements.

ElementDescription
Editor typeSwitch between SQL (write raw SQL) and Query builder (build queries with drop-downs and filters).
Run QueryRuns the current query and refreshes the panel. In the SQL editor you can also use Ctrl+Enter (Windows/Linux) or Cmd+Enter (macOS).
Query typeChoose the result format: Table, Logs, Time series, or Traces. This sets how Grafana interprets and visualizes the results. Available in both SQL and Query builder modes.

In SQL mode:

  • SQL editor — A code editor where you write ClickHouse SQL. It provides schema suggestions (databases, tables, columns) as you type. If SQL validation is enabled in the data source settings, the editor marks invalid syntax.
  • Format code — Use the editor toolbar to format your SQL.
  • Query type — Select Table, Logs, Time series, or Traces so the panel uses the correct visualization.

In Query builder mode:

  • Database and Table — Select the database and table to query from the drop-downs.
  • Query type — Select Table, Logs, Time series, or Traces. The builder shows options that match the type (for example, time column and value columns for time series; columns, filters, group by, and order by for tables).
  • Type-specific options — Configure columns, filters, grouping, sorting, limit (max rows), and (for traces) trace ID. The builder generates the SQL for you.
  • SQL preview — At the bottom of the builder, you can see the generated SQL. You can switch to SQL mode to edit it manually.

Build queries

You can build queries using the SQL editor (raw SQL) or the Query builder. Queries can include macros for dynamic parts such as time range filters.

Query builder modes

When using the query builder, the available options depend on the selected query type:

Query typeBuilder modesDescription
TableList or AggregateList returns raw rows. Aggregate lets you add functions like count(), avg(), and GROUP BY.
Time seriesTrendAutomatically groups by time using $__timeInterval() and applies aggregate functions. Select a time column, one or more value columns, and optional grouping columns.
LogsList or AggregateList returns log rows. Aggregate supports grouping for log volume histograms.
TracesTrace ID or Trace searchTrace ID fetches a single trace by ID. Trace search finds traces matching filters (service name, duration, time range).

Logs query builder

The logs query builder provides structured fields for common log exploration patterns. When Use OTel is enabled, the builder pre-fills column mappings for OpenTelemetry ClickHouse exporter tables.

FieldDescription
Time columnThe high-precision timestamp column used for sorting log rows.
Filter Time columnA lower-precision column for fast time range filtering (for example, a Date or DateTime column indexed for partition pruning). Using a separate filter column can significantly improve query performance.
Log Level columnThe column that contains the log severity level.
Log Message columnThe column that contains the log message body.

You can also filter by log message text using the search field, and add column filters for resource, scope, or log attributes.

Traces query builder

The traces query builder supports two modes:

  • Trace ID mode — Enter a trace ID (or use a template variable like $traceId) to fetch all spans for that trace.
  • Trace search mode — Filter traces by service name, span name, duration range, and time range.

When Use OTel is enabled, column mappings are pre-filled for the OpenTelemetry schema. You can also configure:

FieldDescription
Duration unitThe unit for the duration column (seconds, milliseconds, microseconds, or nanoseconds).
Flatten nestedEnable if your traces table was created with flatten_nested=1.
Events prefixPrefix for event columns (for example, Events.Timestamp, Events.Name).
Links prefixPrefix for link columns (for example, Links.TraceId, Links.SpanId).

Log volume and logs sample

When using the query builder in Explore with the Logs query type, Grafana automatically shows a log volume histogram above the log results and can display a logs sample panel. These supplementary queries are generated by the plugin and run alongside your main query.

Note

Log volume and logs sample are only available when all queries in the panel use the query builder. If any query uses the SQL editor, supplementary queries are disabled.

Time series

For time series visualizations, your query must include a datetime column. Use an alias of time for the timestamp column. Grafana treats timestamp rows without an explicit time zone as UTC. Any column other than time is treated as a value column.

Multi-line time series

To create multi-line time series, the query must return at least 3 columns in this order:

  1. A datetime column with an alias of time
  2. A column to group by (for example, category or label)
  3. One or more metric columns

Example (replace mgbench.logs1 with your database and table):

SQL
SELECT log_time AS time, machine_group, avg(disk_free) AS avg_disk_free
FROM mgbench.logs1
GROUP BY machine_group, log_time
ORDER BY log_time

Tables

Table visualizations are available for any valid ClickHouse query. Select Table in the panel visualization options to view results in tabular form.

Visualize logs with the Logs panel

To use the Logs panel, your query must return a timestamp and string values. To default to the logs visualization in Explore, set the timestamp column alias to log_time.

Example (replace logs1 with your database and table, for example mydb.logs):

SQL
SELECT log_time AS log_time, machine_group, toString(avg(disk_free)) AS avg_disk_free
FROM logs1
GROUP BY machine_group, log_time
ORDER BY log_time

When you don’t have a log_time column, set Format to Logs to force logs rendering (available from plugin version 2.2.0).

Visualize traces with the Traces panel

To use the Traces panel, your data must meet the requirements of the traces panel. Set Format to Trace when building the query (available from plugin version 2.2.0).

If you use the OpenTelemetry Collector and ClickHouse exporter, the following query returns the required column names (case sensitive). Replace the trace ID in the WHERE clause with your trace ID or a template variable (for example $traceId):

SQL
SELECT
  TraceId AS traceID,
  SpanId AS spanID,
  SpanName AS operationName,
  ParentSpanId AS parentSpanID,
  ServiceName AS serviceName,
  Duration / 1000000 AS duration,
  Timestamp AS startTime,
  arrayMap(key -> map('key', key, 'value', SpanAttributes[key]), mapKeys(SpanAttributes)) AS tags,
  arrayMap(key -> map('key', key, 'value', ResourceAttributes[key]), mapKeys(ResourceAttributes)) AS serviceTags,
  if(StatusCode IN ('Error', 'STATUS_CODE_ERROR'), 2, 0) AS statusCode
FROM otel.otel_traces
WHERE TraceId = '61d489320c01243966700e172ab37081'
ORDER BY startTime ASC

Column roles

When you use the Query builder with the Logs, Time series, or Traces query type, each built-in column slot is mapped to a semantic role. The builder renames your columns to the fixed aliases Grafana’s panels expect, so the same panel can visualize data from any ClickHouse schema once you tell it which columns play which roles.

For example, choosing your EventTime column as the Time role for a Logs query produces SELECT EventTime AS timestamp, ...; the Logs panel then sorts on timestamp without needing to know your real column name.

Logs query type

RoleSQL aliasOTel columnCommon non-OTel names
TimetimestampTimestamptimestamp, event_time, @timestamp, created_at
MessagebodyBodymessage, msg, log_message
Log LevellevelSeverityTextlevel, severity, severity_text, log_level

Optional additional columns (OTel mode only): TraceIdtraceID, plus the attribute maps ResourceAttributes, ScopeAttributes, and LogAttributes.

Time series query type

RoleDescription
TimeTimestamp used to order and bucket the series. Must be a DateTime or DateTime64 column. The panel time range filter applies to this column.

Any other selected columns become value series. In Aggregate mode the builder produces GROUP BY on the time column and the aggregated columns.

Traces query type

Trace-panel column aliases are fixed; choose the table columns that play each role.

RoleSQL aliasOTel columnCommon non-OTel names
Trace IDtraceIDTraceIdtrace_id, traceId
Span IDspanIDSpanIdspan_id, spanId
Parent Span IDparentSpanIDParentSpanIdparent_span_id
Service NameserviceNameServiceNameservice, service_name
Operation NameoperationNameSpanNameoperation, operation_name, span_name
Start TimestartTimeTimestampstart_time, timestamp
Duration TimedurationDurationduration, duration_ns, duration_ms
TagstagsSpanAttributestags, attributes
Service TagsserviceTagsResourceAttributesresource, resource_attributes
KindkindSpanKindkind, span_kind
Status CodestatusCodeStatusCodestatus, status_code
Status MessagestatusMessageStatusMessagestatus_message

Set the Duration Unit to match the units your column stores (OTel uses nanoseconds; other schemas often use milliseconds or seconds). The builder converts durations to milliseconds for the trace panel.

To avoid re-mapping roles for every query, configure defaults under Data source settings → Logs and Data source settings → Traces. Enabling OTel mode populates every role with the OTel-conventional column name automatically.

Macros

Macros simplify query syntax and add dynamic parts such as dashboard time range filters. The plugin replaces macros with the corresponding SQL before the query is sent to ClickHouse.

Example query using a time filter macro (replace test_data and date_time with your table and timestamp column):

SQL
SELECT date_time, data_stuff
FROM test_data
WHERE $__timeFilter(date_time)
MacroDescriptionOutput example
$__dateFilter(columnName)Filters by the panel date range using the given column.date >= toDate('2022-10-21') AND date <= toDate('2022-10-23')
$__timeFilter(columnName)Filters by the panel time range (seconds).time >= toDateTime(1415792726) AND time <= toDateTime(1447328726)
$__timeFilter_ms(columnName)Filters by the panel time range (milliseconds).time >= fromUnixTimestamp64Milli(1415792726123) AND time <= fromUnixTimestamp64Milli(1447328726456)
$__dateTimeFilter(dateColumn, timeColumn)Combines date and time filters for separate Date and DateTime columns.date >= toDate('2022-10-21') AND date <= toDate('2022-10-23') AND time >= toDateTime(1415792726) AND time <= toDateTime(1447328726)
$__dt(dateColumn, timeColumn)Shorthand alias for $__dateTimeFilter.Same as $__dateTimeFilter.
$__fromTimeStart of the panel time range as DateTime.toDateTime(1415792726)
$__toTimeEnd of the panel time range as DateTime.toDateTime(1447328726)
$__fromTime_msStart of the panel time range as DateTime64(3).fromUnixTimestamp64Milli(1415792726123)
$__toTime_msEnd of the panel time range as DateTime64(3).fromUnixTimestamp64Milli(1447328726456)
$__interval_sPanel interval in seconds.20
$__timeInterval(columnName)Interval from panel time range (seconds), for grouping.toStartOfInterval(toDateTime(column), INTERVAL 20 second)
$__timeInterval_ms(columnName)Interval from panel time range (milliseconds), for grouping.toStartOfInterval(toDateTime64(column, 3), INTERVAL 20 millisecond)
$__conditionalAll(condition, $templateVar)Uses the first parameter when the template variable does not select all values; otherwise 1=1.condition or 1=1

You can also use brace notation {} when the macro parameter must contain a query or other expression.

Next steps