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

# SQL 기반 시각화

> ClickStack에서 SQL 쿼리로 시각화 만들기

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

ClickStack는 직접 작성한 SQL 쿼리를 기반으로 하는 시각화를 지원합니다. 이를 통해 대시보드 수준의 시간 범위, 필터, 차트 렌더링과 계속 연동하면서도 쿼리 로직을 완전히 제어할 수 있습니다.

SQL 기반 시각화는 기본 제공되는 Chart Explorer만으로는 부족한 작업이 필요할 때 유용합니다. 예를 들어 테이블을 join하거나 차트 빌더에서 지원하지 않는 복잡한 집계를 구성할 때 사용할 수 있습니다.

<div id="creating-a-raw-sql-chart">
  ## SQL 기반 시각화 만들기
</div>

SQL 기반 시각화를 만들려면 대시보드 타일 편집기를 열고 **SQL** 탭을 선택합니다.

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/Wpmp4N2VLv_V8ziJ/images/use-cases/observability/sql-editor-button.png?fit=max&auto=format&n=Wpmp4N2VLv_V8ziJ&q=85&s=5ba724a8938707d92eb6120b2a0b0547" alt="SQL Editor 버튼" size="lg" width="2072" height="599" data-path="images/use-cases/observability/sql-editor-button.png" />

여기서 다음을 수행합니다:

1. 쿼리를 실행할 **ClickHouse 연결**을 선택합니다.
2. 필요에 따라 **Source**를 선택합니다. 이렇게 하면 `$__filters` 매크로를 통해 대시보드 수준 필터를 차트에 적용할 수 있습니다.
3. 편집기에서 SQL 쿼리를 작성하고, 쿼리 매개변수와 매크로를 사용해 대시보드 시간 범위 및 필터와 연동합니다.
4. **실행** 버튼을 클릭해 결과를 미리 본 다음 **저장**합니다.

<div id="query-parameters">
  ## 쿼리 매개변수
</div>

[쿼리 매개변수](/ko/reference/syntax#defining-and-using-query-parameters)를 사용하면 SQL에서 대시보드의 현재 시간 범위와 세분화 수준을 참조할 수 있습니다. 쿼리 매개변수는 ClickHouse 매개변수화 쿼리 구문 `{paramName:Type}`을 사용합니다.

<div id="available-parameters">
  ### 사용 가능한 매개변수
</div>

사용 가능한 매개변수는 차트 유형에 따라 달라집니다.

**Line 및 Stacked Bar 차트:**

| 매개변수                            | 유형    | 설명                           |
| ------------------------------- | ----- | ---------------------------- |
| `{startDateMilliseconds:Int64}` | Int64 | 대시보드 날짜 범위의 시작(epoch 기준 밀리초) |
| `{endDateMilliseconds:Int64}`   | Int64 | 대시보드 날짜 범위의 끝(epoch 기준 밀리초)  |
| `{intervalSeconds:Int64}`       | Int64 | 시간 버킷 크기(세분화 수준 기준, 초 단위)    |
| `{intervalMilliseconds:Int64}`  | Int64 | 시간 버킷 크기(세분화 수준 기준, 밀리초 단위)  |

**Table, Pie 및 Number 차트:**

| 매개변수                            | 유형    | 설명                           |
| ------------------------------- | ----- | ---------------------------- |
| `{startDateMilliseconds:Int64}` | Int64 | 대시보드 날짜 범위의 시작(epoch 기준 밀리초) |
| `{endDateMilliseconds:Int64}`   | Int64 | 대시보드 날짜 범위의 끝(epoch 기준 밀리초)  |

<div id="macros">
  ## 매크로
</div>

매크로는 자주 사용하는 ClickHouse SQL 표현식으로 확장되는 단축 구문입니다. `$__` 접두사가 붙으며, 쿼리가 ClickHouse로 전송되기 전에 치환됩니다.

<div id="time-boundary-macros">
  ### 시간 경계 매크로
</div>

이 매크로는 대시보드의 시작 시간 또는 종료 시간을 나타내는 ClickHouse 표현식을 반환합니다. 인수는 없습니다.

| Macro            | Expands to                                                            | Column type |
| ---------------- | --------------------------------------------------------------------- | ----------- |
| `$__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 및 Stacked-bar 시각화에서만 사용할 수 있습니다.

| 매크로                          | 설명                                                     |
| ---------------------------- | ------------------------------------------------------ |
| `$__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        | Description                                      |
| ------------ | ------------------------------------------------ |
| `$__filters` | 대시보드 수준에서 설정된 필터 조건으로 대체됩니다 (Source가 선택되어 있어야 함) |

차트에서 **Source**가 선택되어 있고 대시보드 필터가 활성화되어 있으면 `$__filters`는 해당 SQL `WHERE` 조건으로 확장됩니다. Source가 선택되지 않았거나 적용된 필터가 없으면 `(1=1)`로 확장되므로 `WHERE` 절에 포함해도 항상 안전합니다.

<div id="how-results-are-plotted">
  ## 쿼리 결과가 차트에 표시되는 방법
</div>

ClickStack는 컬럼 타입에 따라 결과 컬럼을 차트 요소에 자동으로 매핑합니다. 매핑 규칙은 차트 유형별로 다릅니다.

<div id="line-and-stacked-bar-charts">
  ### Line 및 Stacked Bar 차트
</div>

| 역할        | 컬럼 유형                        | 설명                                          |
| --------- | ---------------------------- | ------------------------------------------- |
| **타임스탬프** | 첫 번째 `Date` 또는 `DateTime` 컬럼 | x축으로 사용됩니다.                                 |
| **시리즈 값** | 모든 숫자형 컬럼                    | 각 숫자형 컬럼은 각각 별도의 시리즈로 그려집니다. 일반적으로 집계 값입니다. |
| **그룹 이름** | String, 맵 또는 배열 컬럼           | 선택 사항입니다. 그룹 값이 서로 다른 행은 각각 별도의 시리즈로 그려집니다. |

<div id="pie-chart">
  ### 파이 차트
</div>

| 역할         | 컬럼 유형              | 설명                              |
| ---------- | ------------------ | ------------------------------- |
| **조각 값**   | 첫 번째 숫자형 컬럼        | 각 조각의 크기를 결정합니다.                |
| **조각 레이블** | String, 맵 또는 배열 컬럼 | 선택 사항입니다. 고유한 각 값이 조각 레이블이 됩니다. |

<div id="number-chart">
  ### 숫자 차트
</div>

| 역할     | 컬럼 유형      | 설명                           |
| ------ | ---------- | ---------------------------- |
| **숫자** | 첫 번째 숫자 컬럼 | 첫 번째 숫자 컬럼의 첫 번째 행 값이 표시됩니다. |

<div id="table-chart">
  ### 테이블 차트
</div>

모든 결과 컬럼이 테이블의 컬럼으로 직접 표시됩니다.

<div id="examples">
  ## 예시
</div>

<Info>
  **필수 system table 접근 권한**

  [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` (numeric)는 시리즈 값으로 표시됩니다.
* `ServiceName` (string)은 서비스마다 별도의 선을 생성합니다.

<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-stacked-bar">
  ### 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 Editor는 쿼리 매개변수와 매크로 모두에 대해 자동 완성 제안을 제공합니다.
* 대시보드 필터를 SQL 기반 시각화에 적용하려면 Source를 선택해야 합니다. 정확하게 필터링되도록 Source는 조회하는 테이블과 일치해야 합니다.
