> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifi.life/llms.txt
> Use this file to discover all available pages before exploring further.

# Metric Views 심화: SQL 문법과 조직 전략

> 이 문서는 **[AI/BI](/training/08-ai-bi/overview)** 섹션의 일부입니다.

## Metric View vs 일반 View 비교

| 비교 항목         | 일반 View             | Metric View            |
| ------------- | ------------------- | ---------------------- |
| **용도**        | 범용 데이터 변환           | 비즈니스 메트릭 정의 전용         |
| **자동 집계**     | 없음 (직접 GROUP BY 작성) | 차원 기준 자동 집계            |
| **차원/측정값 구분** | 없음                  | DIMENSION / MEASURE 명시 |
| **AI/BI 연동**  | 수동 설정               | 자동 인식                  |
| **Genie 최적화** | 일반 테이블 취급           | 메트릭 의미 자동 이해           |
| **거버넌스**      | 동일                  | 동일 + 메트릭 전용 리니지        |

***

## Metric View SQL 문법 심화

### 복합 메트릭 (Derived Metric)

기본 측정값을 조합하여 **파생 메트릭** 을 정의할 수 있습니다. 비즈니스에서 자주 사용하는 비율, 전환율 등의 복합 지표를 한 곳에서 관리합니다.

```sql theme={null}
CREATE OR REPLACE METRIC VIEW catalog.schema.ecommerce_metrics
COMMENT '이커머스 핵심 비즈니스 메트릭 (복합 메트릭 포함)'
AS SELECT
  -- 차원 (Dimensions)
  order_date AS time                  DIMENSION COMMENT '주문 날짜',
  region                              DIMENSION COMMENT '판매 지역',
  product_category                    DIMENSION COMMENT '제품 카테고리',
  channel                             DIMENSION COMMENT '판매 채널 (온라인/오프라인/앱)',

  -- 기본 측정값 (Base Measures)
  SUM(order_amount)                   MEASURE total_revenue
                                      COMMENT '총 매출 (환불 제외)',
  COUNT(DISTINCT order_id)            MEASURE order_count
                                      COMMENT '총 주문 건수',
  COUNT(DISTINCT customer_id)         MEASURE unique_customers
                                      COMMENT '고유 고객 수',
  SUM(CASE WHEN is_returned = true THEN 1 ELSE 0 END)
                                      MEASURE return_count
                                      COMMENT '반품 건수',
  SUM(cost_amount)                    MEASURE total_cost
                                      COMMENT '총 비용',

  -- 복합 측정값 (Derived Measures)
  SUM(order_amount) / COUNT(DISTINCT order_id)
                                      MEASURE avg_order_value
                                      COMMENT '평균 주문 금액 (AOV)',
  SUM(order_amount) / COUNT(DISTINCT customer_id)
                                      MEASURE revenue_per_customer
                                      COMMENT '고객당 매출 (ARPU)',
  (SUM(order_amount) - SUM(cost_amount)) / NULLIF(SUM(order_amount), 0) * 100
                                      MEASURE gross_margin_pct
                                      COMMENT '매출 총이익률 (%)',
  SUM(CASE WHEN is_returned = true THEN 1 ELSE 0 END) * 100.0
    / NULLIF(COUNT(DISTINCT order_id), 0)
                                      MEASURE return_rate_pct
                                      COMMENT '반품률 (%)'

FROM catalog.schema.gold_orders
WHERE order_status = 'completed';
```

> 💡 **NULLIF 활용**: 복합 메트릭에서 0으로 나누는 오류를 방지하기 위해 `NULLIF(denominator, 0)`을 사용하는 것이 모범 사례입니다. 0으로 나누면 오류 대신 NULL을 반환합니다.

### 시간 기반 메트릭 (Time-grain)

Metric View에서 `time` 차원을 정의하면, 소비자(Dashboard/Genie)는 자동으로 다양한 시간 단위로 집계할 수 있습니다.

| 시간 단위   | 쿼리 예시                                                            | 설명           |
| ------- | ---------------------------------------------------------------- | ------------ |
| **일별**  | `SELECT time, total_revenue FROM metrics`                        | 기본 시간 단위로 조회 |
| **주별**  | `SELECT DATE_TRUNC('week', time), total_revenue FROM metrics`    | 주 단위 집계      |
| **월별**  | `SELECT DATE_TRUNC('month', time), total_revenue FROM metrics`   | 월 단위 집계      |
| **분기별** | `SELECT DATE_TRUNC('quarter', time), total_revenue FROM metrics` | 분기 단위 집계     |

```sql theme={null}
-- 월별 매출과 전월 대비 증감을 보는 예시
WITH monthly AS (
  SELECT
    DATE_TRUNC('month', time) AS month,
    total_revenue
  FROM catalog.schema.ecommerce_metrics
)
SELECT
  month,
  total_revenue,
  LAG(total_revenue) OVER (ORDER BY month) AS prev_month_revenue,
  (total_revenue - LAG(total_revenue) OVER (ORDER BY month))
    / NULLIF(LAG(total_revenue) OVER (ORDER BY month), 0) * 100 AS mom_growth_pct
FROM monthly
ORDER BY month DESC;
```

### 필터 메트릭 (Filtered Measures)

같은 소스 테이블에서 조건이 다른 여러 메트릭을 정의할 수 있습니다.

```sql theme={null}
CREATE OR REPLACE METRIC VIEW catalog.schema.channel_metrics
COMMENT '채널별 세분화된 매출 메트릭'
AS SELECT
  order_date AS time             DIMENSION,
  region                         DIMENSION,

  -- 전체 매출
  SUM(order_amount)              MEASURE total_revenue
                                 COMMENT '전체 매출',
  -- 온라인 매출만
  SUM(CASE WHEN channel = 'online' THEN order_amount ELSE 0 END)
                                 MEASURE online_revenue
                                 COMMENT '온라인 채널 매출',
  -- 앱 매출만
  SUM(CASE WHEN channel = 'app' THEN order_amount ELSE 0 END)
                                 MEASURE app_revenue
                                 COMMENT '앱 채널 매출',
  -- 온라인 비중
  SUM(CASE WHEN channel = 'online' THEN order_amount ELSE 0 END) * 100.0
    / NULLIF(SUM(order_amount), 0)
                                 MEASURE online_revenue_share_pct
                                 COMMENT '온라인 매출 비중 (%)'

FROM catalog.schema.gold_orders
WHERE order_status = 'completed';
```

***

## 자동 집계 동작 원리 심화

Metric View의 자동 집계는 단순한 매크로가 아니라, **쿼리 리라이트(Query Rewrite)** 엔진에 의해 동작합니다.

### 내부 처리 과정

```
사용자 쿼리:
  SELECT region, total_revenue FROM catalog.schema.revenue_metrics

↓ 쿼리 리라이트 엔진 (Query Planner)

실제 실행되는 SQL:
  SELECT
    region,
    SUM(order_amount) AS total_revenue
  FROM catalog.schema.gold_orders
  WHERE order_status = 'completed'
  GROUP BY region
```

| 단계                 | 설명                                            |
| ------------------ | --------------------------------------------- |
| 1. **파싱**          | 사용자 쿼리에서 SELECT된 DIMENSION과 MEASURE를 식별합니다    |
| 2. **확장**          | MEASURE를 원래 집계 표현식(SUM, COUNT 등)으로 치환합니다      |
| 3. **GROUP BY 생성** | SELECT에 포함된 DIMENSION 컬럼으로 자동 GROUP BY를 구성합니다 |
| 4. **필터 병합**       | Metric View의 기본 WHERE + 사용자 WHERE를 AND로 결합합니다 |
| 5. **최적화**         | SQL Warehouse의 쿼리 옵티마이저가 최적 실행 계획을 생성합니다      |

> ⚠️ **주의사항**: Metric View에서 MEASURE만 SELECT하고 DIMENSION을 하나도 포함하지 않으면, **전체 데이터에 대한 단일 집계** 가 수행됩니다. 대규모 테이블에서는 성능에 주의하세요.

### Genie/Dashboard에서의 자동 집계

Genie에서 Metric View를 사용할 때의 내부 동작을 더 상세히 살펴보겠습니다.

```
사용자: "이번 달 지역별 매출을 보여줘"

1. Genie NLU → 의도 파악: 시간 필터(이번 달) + 차원(region) + 측정값(total_revenue)
2. Metric View 매칭 → revenue_metrics의 total_revenue MEASURE 선택
3. SQL 생성:
   SELECT region, total_revenue
   FROM catalog.schema.revenue_metrics
   WHERE time >= DATE_TRUNC('month', CURRENT_DATE())
4. 자동 집계 엔진 → 실제 SQL로 변환 후 실행
5. 결과를 자연어로 포맷팅하여 반환
```

> 💡 **Metric View가 Genie 정확도를 높이는 이유**: 일반 테이블을 Genie에 연결하면, "매출"이라는 질문에 어떤 컬럼의 어떤 집계(SUM? AVG? 필터 조건?)를 써야 할지 Genie가 추론해야 합니다. Metric View에서는 **측정값의 정의가 명확** 하므로 추론 오류가 크게 줄어듭니다.

***

## dbt Metrics Layer와의 비교

Metric View는 기존 **dbt Semantic Layer(MetricFlow)** 와 유사한 개념을 Databricks 네이티브로 구현한 것입니다.

| 비교 항목        | Databricks Metric View                | dbt Semantic Layer (MetricFlow)        |
| ------------ | ------------------------------------- | -------------------------------------- |
| **정의 방법**    | SQL DDL (CREATE METRIC VIEW)          | YAML 파일 (semantic\_models + metrics)   |
| **실행 엔진**    | SQL Warehouse (네이티브)                  | dbt Cloud Semantic Layer API           |
| **거버넌스**     | Unity Catalog (GRANT/REVOKE, 리니지, 태그) | 별도 관리 필요                               |
| **AI/BI 통합** | Lakeview Dashboard, Genie 네이티브 지원     | BI 도구별 커넥터 필요 (Tableau, Hex 등)         |
| **복합 메트릭**   | SQL 표현식으로 직접 정의                       | derived metrics YAML로 정의               |
| **시간 기반 분석** | time DIMENSION으로 지정                   | time\_spine 테이블 + dimension type: time |
| **필터 메트릭**   | CASE WHEN 또는 WHERE 조합                 | metric filters YAML로 정의                |
| **버전 관리**    | UC 버전 관리 (ALTER/CREATE OR REPLACE)    | Git 기반 YAML 파일 버전 관리                   |
| **학습 곡선**    | SQL 개발자에게 친숙                          | dbt + YAML 학습 필요                       |

> 💡 **하이브리드 접근**: dbt로 데이터 변환(Medallion 파이프라인)을 수행하고, 최종 비즈니스 메트릭은 Metric View로 정의하는 하이브리드 패턴도 가능합니다. dbt는 변환 레이어, Metric View는 소비 레이어로 역할을 분리하는 것입니다.

***

## 대규모 조직에서의 메트릭 관리 전략

### 메트릭 거버넌스 체계

| 거버넌스 수준                    | 적용 방법                                                   | 설명                                    |
| -------------------------- | ------------------------------------------------------- | ------------------------------------- |
| **소유권 (Ownership)**        | `ALTER METRIC VIEW ... SET OWNER TO group_name`         | 각 메트릭에 책임 팀을 명시합니다                    |
| **접근 제어 (Access Control)** | `GRANT SELECT ON METRIC VIEW ... TO group`              | 팀별, 역할별 메트릭 접근을 제어합니다                 |
| **태그 (Tags)**              | `ALTER METRIC VIEW ... SET TAGS ('domain' = 'finance')` | 비즈니스 도메인, 데이터 분류를 태그로 관리합니다           |
| **코멘트 (Documentation)**    | COMMENT 필수 정책                                           | 모든 DIMENSION/MEASURE에 비즈니스 정의를 문서화합니다 |
| **리니지 추적**                 | 자동 (UC가 수집)                                             | 메트릭이 어떤 Gold 테이블에서 파생되었는지 추적합니다       |

### 메트릭 네이밍 컨벤션

대규모 조직에서 수백 개의 메트릭이 생기면, 일관된 네이밍 규칙이 필수입니다.

| 패턴                 | 형식                          | 예시                                                         |
| ------------------ | --------------------------- | ---------------------------------------------------------- |
| **Metric View 이름** | `{domain}_{entity}_metrics` | `finance_revenue_metrics`, `marketing_campaign_metrics`    |
| **MEASURE 이름**     | `{집계}_{대상}` 또는 `{비즈니스_의미}`  | `total_revenue`, `avg_order_value`, `monthly_active_users` |
| **DIMENSION 이름**   | 원본 컬럼명 유지                   | `region`, `product_category`, `customer_segment`           |
| **Time DIMENSION** | `time` (표준)                 | 모든 Metric View에서 `time`으로 통일                               |

### 도메인별 Metric View 설계 패턴

| 카탈로그                  | 스키마             | Metric View            | 설명         |
| --------------------- | --------------- | ---------------------- | ---------- |
| **catalog.analytics** | finance (재무)    | revenue\_metrics       | 매출 메트릭     |
|                       |                 | cost\_metrics          | 비용 메트릭     |
|                       |                 | profitability\_metrics | 수익성 메트릭    |
|                       | marketing (마케팅) | campaign\_metrics      | 캠페인 성과 메트릭 |
|                       |                 | acquisition\_metrics   | 고객 획득 메트릭  |
|                       |                 | retention\_metrics     | 고객 유지 메트릭  |
|                       | operations (운영) | fulfillment\_metrics   | 배송/물류 메트릭  |
|                       |                 | quality\_metrics       | 서비스 품질 메트릭 |

### 메트릭 변경 관리 프로세스

| 단계            | 설명                                       | 담당          |
| ------------- | ---------------------------------------- | ----------- |
| 1. **변경 요청**  | 비즈니스 팀이 메트릭 정의 변경을 요청합니다                 | 비즈니스 사용자    |
| 2. **영향도 분석** | 리니지를 확인하여 영향받는 대시보드/Genie Space를 파악합니다   | 데이터팀        |
| 3. **합의**     | 관련 팀과 새로운 정의에 합의합니다                      | 데이터팀 + 비즈니스 |
| 4. **변경 적용**  | `CREATE OR REPLACE METRIC VIEW`로 업데이트합니다 | 데이터팀        |
| 5. **검증**     | 대시보드와 Genie에서 결과가 올바른지 확인합니다             | QA / 비즈니스   |
| 6. **커뮤니케이션** | 변경 사항을 관련 팀에 공지합니다                       | 데이터팀        |

> ⚠️ **메트릭 변경은 곧 비즈니스 변경**: "매출" 정의를 바꾸면 모든 대시보드의 숫자가 바뀝니다. Metric View의 `CREATE OR REPLACE`는 **즉시 모든 소비자에게 전파** 되므로, 반드시 사전 합의와 테스트를 거쳐야 합니다.

***

## Edge Case와 주의사항

| 주의사항                  | 설명                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------- |
| **중첩 Metric View 불가** | Metric View 위에 또 다른 Metric View를 생성할 수 없습니다. 반드시 물리적 테이블/뷰를 소스로 사용합니다                 |
| **JOIN 지원**           | Metric View 정의에서 JOIN을 사용할 수 있지만, 복잡한 JOIN은 성능에 영향을 줄 수 있습니다                          |
| **Window 함수 제한**      | MEASURE 정의에서 LAG, LEAD 등 윈도우 함수는 직접 사용할 수 없습니다. 소스 뷰에서 미리 계산해야 합니다                    |
| **NULL 처리**           | 차원 컬럼에 NULL이 있으면 별도 그룹으로 집계됩니다. 필요시 COALESCE로 처리합니다                                   |
| **대용량 소스 테이블**        | Metric View는 캐시를 사용하지 않으므로, 매 쿼리마다 소스 테이블을 스캔합니다. Gold 테이블을 적절히 집계하여 소스로 사용하는 것이 좋습니다 |

***

## 정리

| 개념          | 핵심 내용                                             |
| ----------- | ------------------------------------------------- |
| Metric View | 비즈니스 메트릭을 중앙에서 정의하고 일관되게 사용하는 Unity Catalog 기능입니다 |
| 차원 / 측정값    | DIMENSION은 분류 기준, MEASURE는 집계 대상입니다               |
| 자동 집계       | SELECT에 포함된 차원 기준으로 자동 GROUP BY가 적용됩니다            |
| 복합 메트릭      | 기본 측정값을 조합한 파생 지표(비율, 전환율 등)를 정의할 수 있습니다          |
| 필터 메트릭      | CASE WHEN으로 조건별 세분화된 메트릭을 정의합니다                   |
| AI/BI 연동    | Dashboard와 Genie에서 메트릭을 직접 활용할 수 있습니다             |
| 거버넌스        | Unity Catalog의 권한, 리니지, 태그가 그대로 적용됩니다             |
| 메트릭 관리 전략   | 네이밍 컨벤션, 도메인별 분리, 변경 관리 프로세스가 중요합니다               |

***

## 참고 링크

* [Metric View 공식 문서](https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-metric-views.html)
* [Metric View 생성 (CREATE METRIC VIEW)](https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-ddl-create-metric-view.html)
* [AI/BI Dashboard 공식 문서](https://docs.databricks.com/aws/en/dashboards/)
* [Genie 공식 문서](https://docs.databricks.com/aws/en/genie/)
* [Databricks 블로그: Metric Views 소개](https://www.databricks.com/blog/introducing-metric-views)
