dbt

dbt Semantic Layerのmeasures定義ガイド: 集計対象の設計と試験対策

2026-04-19
NicheeLab編集部

dbtのSemantic Layerでは、semantic_model内にmeasures(集計対象)を定義し、後段のmetricsやBIツールから一貫した集計を提供します。

本稿は公式ドキュメントに基づく安定概念(name、agg、expr、代表的な集計種別など)に絞り、バージョン差異の影響が小さい設計原則にフォーカスします。

measuresの基礎: 役割と最小プロパティ

measureは、特定の列(または式)に対して定めた集計規則のことです。semantic_modelが参照する基礎モデルの行に対し、sum・avg・min・max・count・count_distinctなどの集計を定義します。metricsはしばしばこれらのmeasureを組み合わせて利用しますが、measure自体は“何をどう集計するか”を表す最小単位です。

定義はYAMLで行い、一般的にname(一意な名称)、agg(集計種別)、expr(対象列や式)を指定します。countのように行数を数える場合はexprを省略でき、sumやavgでは対象列をexprで明示します。これらはdbtの公式仕様で長く安定している概念です。

  • name: モデル横断で再利用されるため命名は一貫性重視(例: revenue、order_count)
  • agg: sum / avg / min / max / count / count_distinct
  • expr: 集計対象の列名や式(countで省略時は行数カウントを意図)
  • ディメンションやエンティティ(主キー)と併せて定義し、粒度の衝突を避ける

集計設計の落とし穴を避ける

よくある失敗は、粒度が不安定な基礎モデルにmeasureを置くことです。1レコード=1ファクト(例: 1注文、1明細、1日次スナップショット)を満たすモデルにmeasureを定義し、重複結合による二重計上を防ぎます。

NULLや重複の扱いも試験・実務で問われがちです。SUMはNULLを無視しますが、AVGは分母がNULLを除いた件数になる点を理解しておきます。COUNTはCOUNT(*)とCOUNT(col)で意味が違い、COUNT(col)はNULLを無視します。COUNT DISTINCTは非加法的であるため、上位粒度にロールアップすると値が一致しないことがあります。

  • 複数テーブルJOINでmeasure側の粒度が崩れると二重計上が発生
  • COUNTとCOUNT DISTINCTの混同に注意(特にユニークユーザ)
  • 平均は非加法:集計を重ねると値が変わる。必要なら加重平均を検討
  • 時間ディメンションと組み合わせる際は欠損日やタイムゾーンを確認

measureが利用される流れ(概念)

SourcesStaging ModelsFCT/Dim ModelsSemantic Modelentities / dimensions / measures (sum, count, ...)Metrics / QueriesBI, Notebooks, APIsSources → Staging → FCT/Dim → Semantic Model → Metrics / Queries

代表的な集計タイプの比較

集計タイプごとの加法性とNULLの扱いは、試験でも実務でも最重要ポイントです。下表で振る舞いを押さえ、ユースケースに適切なmeasureを選びます。

特に平均と重複排除(COUNT DISTINCT)は非加法で、上位粒度へのロールアップや他ディメンションとの同時集計時に直感と異なる結果になりがちです。

  • SUMはNULLを無視する(多くのSQL方言でSUM(NULL)=NULLではなく、集計結果はNULLを除外)
  • COUNT(*)は行数、COUNT(col)はNULLを除いた件数
  • COUNT DISTINCTは非加法。期間やディメンションを跨ぐと値が一致しない
  • AVGは再集計で値が変わる。必要に応じて分子(合計)と分母(件数)のmeasureから算出
集計タイプ加法性(時間/ディメンション)NULLの扱い典型的な落とし穴
sum加法的(時間・カテゴリともに安全)NULLは無視(多くのSQLで集計から除外)小数の丸め誤差、通貨は桁管理・通貨単位の統一が必要
count加法的(重複しない集合に限る)COUNT(*)は全行、COUNT(col)はNULL除外JOINで重複行が増えると水増し。COUNT(col)のつもりでCOUNT(*)を使う誤り
count_distinct非加法(集合の和で重複が潰れる)NULLは多くの方言でカウント対象外日別ユニークを合計しても月次ユニークに一致しない
avg非加法(再集計で値が変わる)NULLは分母から除外(AVG(col))上位粒度での再平均は誤差。分子/分母measureから算出を検討
min/max非加法(選択関数)NULLは無視されることが多い複数集合の比較では元の分布を反映しない

粒度・エンティティ設計とmeasureの相性

measureは“どの粒度で足し合わせられるか”に直結します。semantic_modelが指す基礎モデルは、明確なエンティティ(例: order_id)や時間ディメンション(例: order_date day)を持ち、1行=1イベントまたは1スナップショットであることが理想です。

エンティティには主キー(primary)と外部キー(foreign)を適切に設定し、ディメンションにはtimeやcategoricalを割り振ります。こうすることで、count_distinctのような非加法measureでも、どの単位で解釈されるかを明確化できます。

  • 1行=1ファクトのモデルにsum系measureを定義する(例: 明細単位の売上)
  • ユーザ数などはcount_distinctだが、期間やセグメントを跨いだ再集計が非加法であることを明示
  • 時間ディメンションは最小粒度(日など)を定義し、上位粒度へはロールアップ
  • 平均・比率は、分子と分母を個別measureで保持し、必要時に計算

YAMLでのmeasure定義: 実務的な最小例

以下は、注文ファクトテーブルを参照するsemantic_modelに対して、典型的なmeasureを定義した例です。sum、count、count_distinctの3種を示しています。avgなどの非加法集計は、必要に応じて分子(sum)と分母(count)を別measureで持つのが安全です。

このレベルの定義は安定した仕様に基づくため、dbtのバージョン差異の影響を受けにくく、試験でも強く問われます。

  • sumは対象列をexprで指定(数値型を推奨)
  • countはexpr省略可(行数カウント)
  • count_distinctは対象列をexprで明示
  • 時間ディメンションの最小粒度を定めておく(dayなど)

semantic_model内でのmeasure定義(YAML)

semantic_models:
  - name: orders
    model: ref('fct_orders')
    entities:
      - name: order_id
        type: primary
      - name: customer_id
        type: foreign
    dimensions:
      - name: order_date
        type: time
        type_params:
          time_granularity: day
      - name: status
        type: categorical
    measures:
      - name: revenue
        agg: sum
        expr: total_amount
      - name: order_count
        agg: count
      - name: customer_count
        agg: count_distinct
        expr: customer_id

検証・テストと試験対策ポイント

measureの品質は基礎モデルの品質に依存します。主キーの一意性、外部キーの被参照整合性、金額列の型・スケール、時間ディメンションの欠損などをdbt testで確かめます。また、簡単な検証SQLでサンプル期間の期待値と突合し、JOINで水増しがないかを確認します。

試験対策としては、加法性、NULLの扱い、COUNTとCOUNT DISTINCTの違い、平均の再集計不可、measureの粒度要件(1行=1ファクト)を説明できることが重要です。

  • dbt testでnot_null/uniqueを主キーに、accepted_valuesでステータス列を検証
  • 金額列は数値型・通貨単位の統一、丸め位置をモデル側で明確化
  • 検証SQLでSUMとCOUNTの期待値を小さなサンプルで手計算と照合
  • 平均・率は分子/分母measureから派生させる癖を付ける

問題で確認

Analytics Engineer

問題 1

dbt Semantic Layerで月次売上合計とユニーク購入者数を正しく定義したい。適切なmeasure定義の組み合わせとして最も妥当なのはどれか。

  1. 売上はagg: sumで金額列をexprに指定、購入者はagg: count_distinctでcustomer_idをexprに指定する
  2. 売上はagg: avgで金額列をexprに指定、購入者はagg: countでexpr省略する
  3. 売上はagg: sumでexpr省略、購入者はagg: count_distinctでexpr省略する
  4. 売上はagg: countで行数をカウント、購入者はagg: avgでcustomer_idをexprに指定する

正解: A

売上合計はsumで金額列を明示、ユニーク購入者数はcount_distinctで対象ID列を明示するのが正解。avgは平均のため合計には不適切。countは行数であり、顧客の一意数にはならない。

よくある質問

measureのcountでexprを省略すると何を数える?

多くの実装で行数をカウントします。特定列のNULLを除外したい場合はCOUNT(col)に相当するよう、対象列をexprで明示してください。

平均や率はmeasureで直接定義すべき?

再集計時の歪みを避けるため、分子(例: sum_revenue)と分母(例: order_count)を別々のmeasureとして定義し、利用側で計算するのが安全です。

count_distinctはなぜ非加法なのか?

集合の重複を潰すため、異なる期間やディメンションで算出した値を単純合算しても、重なり分が二重計上されません。したがって粒度を上げると元の値と一致しないことがあります。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.