跳转到主内容
跳转到主内容

基于 SQL 的可视化

ClickStack 支持基于原始 SQL 查询的可视化。这让您能够完全控制查询逻辑,同时仍能与仪表板级别的时间范围、仪表板级筛选器和图表渲染集成。

当您需要实现内置 Chart Explorer 之外的功能时,基于 SQL 的可视化会非常有用——例如,关联表,或构建图表构建器不支持的复杂聚合。

创建基于 SQL 的可视化

要创建基于 SQL 的可视化,请打开仪表板图块编辑器并选择 SQL 选项卡。

SQL 编辑器按钮

接下来:

  1. 选择一个 ClickHouse 连接 作为运行查询的目标。
  2. 可选择一个 数据源——这样可通过 $__filters 宏将仪表板级筛选器应用到图表。
  3. 在编辑器中编写 SQL 查询,并使用查询参数和宏与仪表板的时间范围及筛选器集成。
  4. 点击 play 按钮预览结果,然后点击 Save

查询参数

查询参数 允许您在 SQL 中引用仪表板当前的时间范围和粒度。它们使用 ClickHouse 参数化查询语法:{paramName:Type}

Available parameters

可用参数取决于图表类型:

折线图和堆叠条形图:

ParameterTypeDescription
{startDateMilliseconds:Int64}Int64仪表板日期范围的开始时间(自 Unix 纪元以来的毫秒数)
{endDateMilliseconds:Int64}Int64仪表板日期范围的结束时间(自 Unix 纪元以来的毫秒数)
{intervalSeconds:Int64}Int64时间桶大小,以秒为单位(基于粒度)
{intervalMilliseconds:Int64}Int64时间桶大小,以毫秒为单位(基于粒度)

表格、饼图和数值图表:

ParameterTypeDescription
{startDateMilliseconds:Int64}Int64仪表板日期范围的开始时间(自 Unix 纪元以来的毫秒数)
{endDateMilliseconds:Int64}Int64仪表板日期范围的结束时间(自 Unix 纪元以来的毫秒数)

宏是可展开为常见 ClickHouse SQL 表达式的简写。它们以 $__ 为前缀,并会在查询发送到 ClickHouse 之前完成替换。

时间边界宏

这些宏会返回一个表示仪表板起始时间或结束时间的 ClickHouse 表达式。它们不接受任何参数。

Macro展开为列类型
$__fromTimetoDateTime(fromUnixTimestamp64Milli({startDateMilliseconds:Int64}))DateTime
$__toTimetoDateTime(fromUnixTimestamp64Milli({endDateMilliseconds:Int64}))DateTime
$__fromTime_msfromUnixTimestamp64Milli({startDateMilliseconds:Int64})DateTime64
$__toTime_msfromUnixTimestamp64Milli({endDateMilliseconds:Int64})DateTime64
$__interval_s{intervalSeconds:Int64}Int64

时间过滤宏

这些宏会生成 WHERE 子句片段,用于按仪表板的时间范围过滤列。

Macro描述
$__timeFilter(column)按仪表板时间范围过滤 DateTime
$__timeFilter_ms(column)按仪表板时间范围过滤 DateTime64 (毫秒) 列
$__dateFilter(column)按仪表板时间范围过滤 Date
$__dateTimeFilter(dateCol, timeCol)使用单独的 Date 列和 DateTime 列进行过滤
$__dt(dateCol, timeCol)$__dateTimeFilter 的别名

$__timeFilter(TimestampTime)展开示例

TimestampTime >= toDateTime(fromUnixTimestamp64Milli({startDateMilliseconds:Int64}))
AND TimestampTime <= toDateTime(fromUnixTimestamp64Milli({endDateMilliseconds:Int64}))

时间间隔宏

这些宏会将时间戳列按与仪表板粒度匹配的时间间隔进行分桶。它们通常用于时间序列图表的 SELECTGROUP BY 子句中。仅适用于折线图和堆叠条形图可视化。

Macro描述
$__timeInterval(column)DateTime 列按 intervalSeconds 的时间间隔进行分桶
$__timeInterval_ms(column)DateTime64 列按 intervalMilliseconds 的时间间隔进行分桶

$__timeInterval(TimestampTime)展开示例

toStartOfInterval(toDateTime(TimestampTime), INTERVAL {intervalSeconds:Int64} second)

Dashboard filter macro

MacroDescription
$__filters替换为仪表板级筛选器条件(需要先选择一个数据源)

当在图表上选择了数据源且仪表板级筛选器处于启用状态时,$__filters 会展开为对应的 SQL WHERE 条件。未选择数据源或未应用任何筛选器时,它会展开为 (1=1),因此始终可以安全地将其包含在 WHERE 子句 中。

How query results are plotted

ClickStack 会根据列类型自动将结果列映射到图表元素。不同图表类型的映射规则有所不同。

折线图和堆叠条形图

角色列类型描述
时间戳第一个 DateDateTime用作 x 轴。
序列值所有数值列每个数值列都会绘制为一个单独的序列。这些通常是聚合值。
分组名称String、Map 或 Array 列可选。分组值不同的行会绘制为单独的序列。

饼图

角色列类型描述
切片值第一个数值列决定各个扇区的大小。
切片标签String、Map 或 Array 列可选。每个唯一值都会成为一个扇区标签。

数值图表

RoleColumn typeDescription
NumberFirst numeric column显示第一个数值列第一行的值。

表格图表

所有结果列都会直接显示为表格列。

示例

必需的 system table 访问权限

如果要在 play-clickstack.clickhouse.com 上运行以下示例,则需要指定 otel_v2.otel_logsotel_v2.otel_traces

折线图表 — 按服务划分的日志计数随时间变化

此查询按服务统计日志事件数,并按与仪表板粒度一致的时间间隔进行分桶。

SELECT
  toStartOfInterval(TimestampTime, INTERVAL {intervalSeconds:Int64} second) AS ts,
  ServiceName,
  count() AS count
FROM otel_logs
WHERE TimestampTime >= fromUnixTimestamp64Milli({startDateMilliseconds:Int64})
  AND TimestampTime < fromUnixTimestamp64Milli({endDateMilliseconds:Int64})
  AND $__filters
GROUP BY ServiceName, ts
ORDER BY ts ASC
  • ts (DateTime) 用作 x 轴时间戳。
  • count (numeric) 作为序列值绘制。
  • ServiceName (string) 为每个服务生成一条单独的线。

折线图表 — 使用宏

为简洁起见,下面是使用宏写法的相同查询:

SELECT
  $__timeInterval(TimestampTime) AS ts,
  ServiceName,
  count() AS count
FROM otel_logs
WHERE $__timeFilter(TimestampTime)
  AND $__filters
GROUP BY ServiceName, ts
ORDER BY ts ASC

堆叠条形图表 — 按严重程度划分的错误计数

SELECT
  $__timeInterval(TimestampTime) AS ts,
  lower(SeverityText),
  count() AS count
FROM otel_logs
WHERE $__timeFilter(TimestampTime)
  AND lower(SeverityText) IN ('error', 'warn')
  AND $__filters
GROUP BY SeverityText, ts
ORDER BY ts ASC

Table chart — 前 10 个最慢的 endpoint

SELECT
  SpanName AS endpoint,
  avg(Duration) / 1000 AS avg_duration_ms,
  count() AS request_count
FROM otel_traces
WHERE $__timeFilter(Timestamp)
  AND $__filters
GROUP BY SpanName
ORDER BY avg_duration_ms DESC
LIMIT 10

饼图图表 — 按服务划分的请求分布

SELECT
  ServiceName,
  count() AS request_count
FROM otel_traces
WHERE $__timeFilter(Timestamp)
  AND $__filters
GROUP BY ServiceName
  • request_count (numeric) 决定每个切片的大小。
  • ServiceName (string) 用作每个切片的标签。

数值图表 — 错误总数

SELECT
  count() AS total_errors
FROM otel_logs
WHERE $__timeFilter(TimestampTime)
  AND SeverityText = 'error'
  AND $__filters

将显示第一行中的单个数值 total_errors

注意事项

  • 基于 SQL 的可视化会在启用 readonly 模式时执行——仅允许 SELECT 查询。
  • 基于 SQL 的可视化必须且只能包含一个 SQL 查询,不支持多个查询。
  • SQL 编辑器会为查询参数和宏提供自动补全建议。
  • 必须先选择一个数据源,才能将仪表板筛选器应用到基于 SQL 的可视化。该数据源应与所查询的表一致,以确保筛选准确。