> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-detect-table-modification.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Визуализации на основе SQL

> Создание визуализаций с помощью SQL-запросов в ClickStack

export const Image = ({img, alt, size = "lg", background}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  const backgroundColor = background === "white" ? "white" : background === "black" ? "rgb(31 31 28)" : undefined;
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} style={{
    backgroundColor
  }} />
      </Frame>
    </div>;
};

ClickStack поддерживает визуализации на основе SQL-запросов в исходном виде. Это дает полный контроль над логикой запроса, сохраняя интеграцию с временными диапазонами на уровне панели мониторинга, фильтрами и отрисовкой диаграмм.

Визуализации на основе SQL полезны, когда нужно выйти за рамки встроенного Chart Explorer — например, чтобы объединять таблицы с помощью JOIN или строить сложные агрегации, которые не поддерживаются chart builder.

<div id="creating-a-raw-sql-chart">
  ## Создание визуализации на основе SQL
</div>

Чтобы создать визуализацию на основе SQL, откройте редактор плитки панели мониторинга и выберите вкладку **SQL**.

<Image img="https://mintcdn.com/private-7c7dfe99-detect-table-modification/F_d8MuIzyuviDyOr/images/use-cases/observability/sql-editor-button.webp?fit=max&auto=format&n=F_d8MuIzyuviDyOr&q=85&s=7da8b2b835783f8f9155984a4d43c65a" alt="Кнопка редактора SQL" size="lg" width="2072" height="599" data-path="images/use-cases/observability/sql-editor-button.webp" />

Далее:

1. Выберите **подключение к ClickHouse**, для которого будет выполняться запрос.
2. При необходимости выберите **Source** — это позволит применять к вашей визуализации фильтры уровня панели мониторинга через макрос `$__filters`.
3. Напишите SQL-запрос в редакторе, используя параметры запроса и макросы для интеграции с временным диапазоном, фильтрами и переменными панели мониторинга.
4. Нажмите кнопку **play**, чтобы просмотреть результат, затем нажмите **Save**.

<div id="query-parameters">
  ## Параметры запроса
</div>

[Параметры запроса](/ru/reference/syntax#defining-and-using-query-parameters) позволяют использовать в SQL текущий временной диапазон и уровень детализации панели мониторинга. Для этого применяется синтаксис параметризованных запросов ClickHouse: `{paramName:Type}`.

<div id="available-parameters">
  ### Доступные параметры
</div>

Доступные параметры зависят от типа диаграммы:

**Диаграммы Line и столбчатые диаграммы с накоплением:**

| Параметр                        | Тип   | Описание                                                                     |
| ------------------------------- | ----- | ---------------------------------------------------------------------------- |
| `{startDateMilliseconds:Int64}` | Int64 | Начало диапазона дат панели мониторинга (миллисекунды с начала эпохи Unix)   |
| `{endDateMilliseconds:Int64}`   | Int64 | Конец диапазона дат панели мониторинга (миллисекунды с начала эпохи Unix)    |
| `{intervalSeconds:Int64}`       | Int64 | Размер временного интервала в секундах (в зависимости от гранулярности)      |
| `{intervalMilliseconds:Int64}`  | Int64 | Размер временного интервала в миллисекундах (в зависимости от гранулярности) |

**Диаграммы Table, Pie и Number:**

| Параметр                        | Тип   | Описание                                                                   |
| ------------------------------- | ----- | -------------------------------------------------------------------------- |
| `{startDateMilliseconds:Int64}` | Int64 | Начало диапазона дат панели мониторинга (миллисекунды с начала эпохи Unix) |
| `{endDateMilliseconds:Int64}`   | Int64 | Конец диапазона дат панели мониторинга (миллисекунды с начала эпохи Unix)  |

<div id="macros">
  ## Макросы
</div>

Макросы — это сокращённые конструкции, которые разворачиваются в типовые выражения ClickHouse SQL. Они начинаются с префикса `$__` и заменяются до отправки запроса в ClickHouse.

<div id="time-boundary-macros">
  ### Макросы временных границ
</div>

Эти макросы возвращают выражение ClickHouse, соответствующее времени начала или окончания панели мониторинга. Они не принимают аргументов.

| Макрос           | Раскрывается в                                                        | Тип столбца |
| ---------------- | --------------------------------------------------------------------- | ----------- |
| `$__fromTime`    | `toDateTime(fromUnixTimestamp64Milli({startDateMilliseconds:Int64}))` | DateTime    |
| `$__toTime`      | `toDateTime(fromUnixTimestamp64Milli({endDateMilliseconds:Int64}))`   | DateTime    |
| `$__fromTime_ms` | `fromUnixTimestamp64Milli({startDateMilliseconds:Int64})`             | DateTime64  |
| `$__toTime_ms`   | `fromUnixTimestamp64Milli({endDateMilliseconds:Int64})`               | DateTime64  |
| `$__interval_s`  | `{intervalSeconds:Int64}`                                             | Int64       |

<div id="time-filter-macros">
  ### Макросы фильтрации по времени
</div>

Эти макросы создают фрагмент условия `WHERE`, который фильтрует столбец по временному диапазону панели мониторинга.

| Макрос                                | Описание                                                                                 |
| ------------------------------------- | ---------------------------------------------------------------------------------------- |
| `$__timeFilter(column)`               | Фильтрует столбец `DateTime` по временному диапазону панели мониторинга                  |
| `$__timeFilter_ms(column)`            | Фильтрует столбец `DateTime64` (миллисекунды) по временному диапазону панели мониторинга |
| `$__dateFilter(column)`               | Фильтрует столбец `Date` по временному диапазону панели мониторинга                      |
| `$__dateTimeFilter(dateCol, timeCol)` | Фильтрует с использованием отдельных столбцов `Date` и `DateTime`                        |
| `$__dt(dateCol, timeCol)`             | Псевдоним для `$__dateTimeFilter`                                                        |

**Пример развёртывания** `$__timeFilter(TimestampTime)`:

```sql theme={null}
TimestampTime >= toDateTime(fromUnixTimestamp64Milli({startDateMilliseconds:Int64}))
AND TimestampTime <= toDateTime(fromUnixTimestamp64Milli({endDateMilliseconds:Int64}))
```

<div id="time-interval-macros">
  ### Макросы временных интервалов
</div>

Эти макросы группируют столбец с временной меткой по интервалам, соответствующим детализации панели мониторинга. Обычно они используются в секциях `SELECT` и `GROUP BY` для графиков временных рядов. Они доступны только для визуализаций Line и столбчатых диаграмм с накоплением.

| Macro                        | Description                                                          |
| ---------------------------- | -------------------------------------------------------------------- |
| `$__timeInterval(column)`    | Группирует столбец `DateTime` по интервалам `intervalSeconds`        |
| `$__timeInterval_ms(column)` | Группирует столбец `DateTime64` по интервалам `intervalMilliseconds` |

**Пример развёртывания** `$__timeInterval(TimestampTime)`:

```sql theme={null}
toStartOfInterval(toDateTime(TimestampTime), INTERVAL {intervalSeconds:Int64} second)
```

<div id="dashboard-filter-macro">
  ### Макрос фильтра панели мониторинга
</div>

| Macro        | Описание                                                                               |
| ------------ | -------------------------------------------------------------------------------------- |
| `$__filters` | Подставляет условия фильтрации на уровне панели мониторинга (требуется выбрать Source) |

Когда на графике выбран **Source** и включены фильтры панели мониторинга, `$__filters` разворачивается в соответствующие условия SQL `WHERE`. Если источник не выбран или фильтры не заданы, он разворачивается в `(1=1)`, поэтому его всегда можно безопасно включать в условие `WHERE`.

`$__filters` применяет только фильтры с включенным параметром **Broadcast filter condition**. Фильтры, представленные как переменные, указываются явно, как описано ниже.

<div id="dashboard-variables">
  ### Макросы переменных панели мониторинга
</div>

Если фильтр панели мониторинга [доступен в качестве переменной](/ru/clickstack/features/dashboards/overview#dashboard-variables), его выбранные значения можно использовать в любом месте запроса. Эти макросы доступны только в плитках панели мониторинга, в которой объявлена хотя бы одна переменная.

| Макрос                                        | Описание                                                                                                                              |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `$__filter($<variable>)`                      | Разворачивается в `toString(<filter expression>) IN ($variable)`, если для `variable` выбраны значения, и в `1=1` в противном случае. |
| `$__filter(<expression>, $<variable>)`        | Разворачивается в `<expression> IN ($variable)`, если для `variable` выбраны значения, и в `1=1` в противном случае.                  |
| `$__conditionalAll(<condition>, $<variable>)` | Разворачивается в `<condition>`, если выбрано значение переменной, и в `1=1` в противном случае.                                      |

Значения переменной также можно подставлять напрямую как `$name` или `${name}`, указав необязательный формат: `${name:sqlstring}` (по умолчанию), `${name:csv}` или `${name:regex}`. В формате по умолчанию прямая ссылка до выбора значения отображается как `NULL`, поэтому везде, где ожидается предикат, используйте указанные выше макросы.

<div id="how-results-are-plotted">
  ## Как результаты запроса отображаются на диаграмме
</div>

ClickStack автоматически сопоставляет столбцы результатов с элементами диаграммы в зависимости от типов столбцов. Правила сопоставления зависят от типа диаграммы.

<div id="line-and-stacked-bar-charts">
  ### Линейные диаграммы и столбчатые диаграммы с накоплением
</div>

| Роль                | Тип столбца                          | Описание                                                                                      |
| ------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------- |
| **Временная метка** | Первый столбец `Date` или `DateTime` | Используется как ось X.                                                                       |
| **Значение серии**  | Все числовые столбцы                 | Каждый числовой столбец отображается как отдельная серия. Обычно это агрегированные значения. |
| **Названия групп**  | Столбцы String, Map или Array        | Необязательно. Строки с разными значениями групп отображаются как отдельные серии.            |

<div id="pie-chart">
  ### Круговая диаграмма
</div>

| Роль                 | Тип столбца                        | Описание                                                             |
| -------------------- | ---------------------------------- | -------------------------------------------------------------------- |
| **Значение сектора** | Первый числовой столбец            | Определяет размер каждого сектора.                                   |
| **Метка сектора**    | Столбцы типа String, Map или Array | Необязательно. Каждое уникальное значение становится меткой сектора. |

<div id="number-chart">
  ### Числовая диаграмма
</div>

| Роль      | Тип столбца             | Описание                                                          |
| --------- | ----------------------- | ----------------------------------------------------------------- |
| **Число** | Первый числовой столбец | Отображается значение из первой строки первого числового столбца. |

<div id="table-chart">
  ### Табличная диаграмма
</div>

Все столбцы результатов отображаются непосредственно в виде столбцов таблицы.

<div id="examples">
  ## Примеры
</div>

<Info>
  **Требуется доступ к системной таблице**

  Если вы запускаете следующие примеры на [play-clickstack.clickhouse.com](https://play-clickstack.clickhouse.com), необходимо указать `otel_v2.otel_logs` или `otel_v2.otel_traces`.
</Info>

<div id="example-line-chart">
  ### Линейная диаграмма — количество логов по сервисам во времени
</div>

Этот запрос подсчитывает количество событий логов для каждого сервиса, группируя их по временным интервалам в соответствии с детализацией панели мониторинга.

```sql theme={null}
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` (числовое значение) отображается как значение серии.
* `ServiceName` (строка) создает отдельную линию для каждого сервиса.

<div id="example-line-chart-macros">
  ### Линейная диаграмма — с использованием макросов
</div>

Тот же запрос с использованием макросов для краткости:

```sql theme={null}
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
```

<div id="example-line-chart-variables">
  ### Линейный график — использование переменных панели мониторинга
</div>

Для панели мониторинга с переменной `service`, связанной с `ServiceName`, и переменной `severity`, связанной с `SeverityText`, этот запрос ограничивает диаграмму текущим выбранным сервисом и исключает выбранные уровни серьёзности. Если для переменной не выбрано значение, оба макроса разворачиваются в `1=1`, поэтому до выбора значения пользователем диаграмма отображается без фильтрации.

```sql theme={null}
SELECT
  $__timeInterval(TimestampTime) AS ts,
  count() AS count
FROM otel_logs
WHERE $__timeFilter(TimestampTime)
  AND $__filter(ServiceName, $service)
  AND $__conditionalAll(SeverityText NOT IN ($severity), $severity)
GROUP BY ts
ORDER BY ts ASC
```

<div id="example-stacked-bar">
  ### Столбчатая диаграмма с накоплением — количество ошибок по уровням серьёзности
</div>

```sql theme={null}
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
```

<div id="example-table">
  ### Табличная диаграмма — 10 конечных точек с наибольшей задержкой
</div>

```sql theme={null}
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
```

<div id="example-pie">
  ### Круговая диаграмма — распределение запросов по сервисам
</div>

```sql theme={null}
SELECT
  ServiceName,
  count() AS request_count
FROM otel_traces
WHERE $__timeFilter(Timestamp)
  AND $__filters
GROUP BY ServiceName
```

* `request_count` (числовое значение) определяет размер каждого сегмента.
* `ServiceName` (строка) задает метку каждого сегмента.

<div id="example-number">
  ### Числовая диаграмма — общее число ошибок
</div>

```sql theme={null}
SELECT
  count() AS total_errors
FROM otel_logs
WHERE $__timeFilter(TimestampTime)
  AND SeverityText = 'error'
  AND $__filters
```

Отображается числовое значение `total_errors` из первой строки.

<div id="notes">
  ## Примечания
</div>

* Визуализации на основе SQL выполняются во включенном режиме `readonly` — разрешены только запросы `SELECT`.
* Визуализации на основе SQL должны содержать ровно один SQL-запрос — несколько запросов не поддерживаются.
* Редактор SQL предлагает автодополнение как для параметров запроса, так и для макросов.
* Чтобы фильтры панели мониторинга применялись к визуализациям на основе SQL, необходимо выбрать Source. Для корректной фильтрации Source должен соответствовать таблице, к которой обращается запрос.
* Для переменных панели мониторинга Source не требуется — значения берутся из выпадающих списков фильтров панели мониторинга, а не из собственного Source блока.
* Оповещения для SQL-блока, ссылающегося на переменную панели мониторинга, вычисляются для каждой переменной в пустом состоянии, а не со значениями, выбранными на панели мониторинга.
