概要
KPI ツリー(GMV逆算型)
ノースタースター指標(GMV)から逆算して、客数・客単価・効率・品質の4軸にKPIを分解する。「クーポンが好調か」ではなく「GMVに何%貢献したか」を起点にする。
OKR 計測可能化
KR に「測定方法・現状値・目標値・期限」の4点セットを付ける。dbt モデル名を測定方法に明記することで、エンジニアとビジネス側の共通言語になる。
6W3H ダッシュボード設計
誰が(Who)→ 何を(What)→ いつ(When)の順で設計。閲覧者の役割(担当者/リーダー/経営層)で必要な粒度が変わる。3層設計が基本。
クーポン ROI = 追加GMV / 割引コスト
ROI が 1.0x 以下は投資回収できていない。業界標準は 2.0〜3.0x。dbt の mart_coupon_kpi_daily で日次自動計算し、1.5x 以下でアラートを設定する。
問題
ECサイトの販促チームから「クーポン施策の費用対効果が見えない」というオーダーが来た。現在、月次で手動集計したExcelレポートを出しているが、数値が各部署バラバラで信頼性に欠ける。あなたはMOpsエンジニア兼PM補佐として、クーポン施策の KPI 体系を再設計し、ダッシュボード化戦略と OKR への接続方法を提案せよ。
前提条件
- 月間ユニークユーザー: 約80万人
- クーポン月間発行数: 約50万枚 / 使用率: 約22%(業界平均 25〜30%)
- 現在の割引コスト: 月額約1,200万円
- EC売上のノースタースター指標: 月次 GMV
- BigQuery + dbt + Looker Studio 環境が整備済み
期待する回答形式: (1) KPI 体系設計(ツリー構造)、(2) OKR への接続案(Objective + 2〜3 KR)、(3) ダッシュボード設計方針(6W3H)、(4) 優先計測指標と dbt モデルスケルトン
現状分析 (Before) — 4つの構造的問題
4つの問題が「見えない費用対効果」を生み出しています。分析してください。
❌ 現状の管理体制
# ❌ 問題1: データが分散・バラバラ
割引率 → スプレッドシートA(マーケティング部)
発行数 → スプレッドシートB(システム部)
使用数 → スプレッドシートC(CRM部)
売上 → スプレッドシートD(EC部)
# ❌ 問題2: 判断基準が存在しない
「クーポン施策が効いているかどうか」
→ 担当者の感覚判断のみ
→ ROI の定義すらなし
# ❌ 問題3: クーポンコードの使い回し
coupon_code: "SUMMER10"
→ 夏季キャンペーンで使用
→ 翌月の離脱防止施策でも使用
→ どちらの効果か不明(Attribution汚染)
# ❌ 問題4: 月次レポートのタイムラグ
施策実施 → 月末集計 → 翌月5日にレポート
→ 効果がわかる頃には次施策が走っている
→ PDCAサイクルが月1回しか回らない
✅ 目指す状態(After)
# ✅ 解決1: 単一の真実のソース(SSOT)
BigQuery: raw.orders + raw.coupons
→ dbt: stg_ → int_ → mart_coupon_kpi_daily
→ 全部署が同じ数値を参照
# ✅ 解決2: KPI ツリーで判断基準を明確化
クーポン ROI = 追加GMV / 割引コスト
→ 1.8x(現状) → 2.5x(目標)
# ✅ 解決3: キャンペーン ID で完全分離
coupon_code に campaign_id を紐付け
→ 同一コードでも campaign 別に効果測定
→ Attribution が明確
# ✅ 解決4: 日次自動レポート
dbt run → mart_coupon_kpi_daily 更新(毎朝6時)
→ Looker Studio 自動更新(9時配信)
→ Slack Webhook で日次サマリ通知
→ PDCAサイクルが翌日に回る
ヒント(段階的開示)
ヒント1 — 方向性
KPI 設計の基本は「ノースタースター指標(GMV)から逆算してツリーを作る」こと。クーポン施策は GMV に 2 つのルートで影響する: (a) 客数増加(新規獲得・離脱防止)、(b) 客単価変動(割引コスト vs バスケットサイズ拡大)。どちらのルートで KPI を置くかで OKR も変わる。まず「自社のクーポンはどちらが主目的か」を定義することが先決。
ヒント2 — アプローチ(KPI ツリーの構成要素)
- 効果指標: 使用率(Usage Rate)・追加購買率(Incremental Purchase Rate)・バスケットサイズ変化
- 効率指標: 割引コスト / 追加 GMV(クーポン ROI)・クーポン CPO(Cost Per Order)
- 品質指標: 新規 vs 既存の使用比率・転用率・重複使用率
ヒント3 — dbt モデル骨格と6W3H
-- mart_coupon_kpi_daily.sql の骨格
SELECT
order_date,
coupon_code,
campaign_name,
SUM(net_sales) AS incremental_gmv,
SUM(discount_amount) AS discount_cost,
SAFE_DIVIDE(SUM(net_sales), SUM(discount_amount)) AS coupon_roi, -- KR1
COUNT(DISTINCT order_id) AS order_count,
COUNT(DISTINCT user_id)
/ MAX(daily_total_users) AS usage_rate -- KR2
FROM {{ ref('int_coupon_orders_joined') }}
WHERE order_date >= DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 30 DAY)
GROUP BY order_date, coupon_code, campaign_name
6W3H でダッシュボードを設計する際は「Who(閲覧者3層)→ What → When」の順に詰めると、粒度設計が自然にできる。
問題点分析
| # | 問題点 | ビジネス影響 | 解決方法 |
|---|---|---|---|
| 1 | KPI がなく判断基準が感覚頼り | ROI が 1.0x 以下の施策(損失)を継続するリスク。月額1,200万円の割引コストが正当化できない | クーポン ROI(追加GMV / 割引コスト)を主 KPI に設定。目標 2.5x |
| 2 | データが複数スプレッドシートに分散 | 部署間で数値が一致せず会議で時間を浪費。意思決定が遅れる | BigQuery + dbt を SSOT(Single Source of Truth)に。全部署が同じモデルを参照 |
| 3 | クーポンコードの使い回し(Attribution汚染) | どのキャンペーンが効いたかわからない。ROI が混在してしまう | campaign_id を coupon_code に紐付け。dbt で campaign_name 別に集計 |
| 4 | 月次レポートでタイムラグが1ヶ月 | 施策の問題に気づいた頃には次施策が走っており、修正機会を逃す | dbt 日次バッチ + Looker Studio 自動更新で翌朝9時にレポート配信 |
KPI ツリー図 — GMV 逆算型
模範解答
1. OKR(Q2 2026)
Objective: クーポン施策をデータドリブンに再設計し、GMV への正味貢献度を最大化する
| KR | 内容 | 測定方法(dbt) | 現状値 | 目標値 |
|---|---|---|---|---|
| KR1 | クーポン ROI(追加GMV / 割引コスト)を改善する | mart_coupon_kpi_daily.coupon_roi 月次平均 |
1.8x | 2.5x |
| KR2 | クーポン使用率を業界平均以上に引き上げる | mart_coupon_kpi_daily.usage_rate 30日移動平均 |
22% | 27% |
| KR3 | 施策効果レポーティングを月次 → 日次に移行する | Looker Studio + Slack Webhook 稼働率 | 月次Excel | 日次自動配信 99%+ |
2. ダッシュボード設計方針(6W3H)
| 項目 | 内容 |
|---|---|
| Who(誰が見る) | 3層: ①販促担当(クーポン別詳細)②チームリーダー(キャンペーン別ROI)③経営層(GMV貢献サマリ) |
| What(何を見る) | クーポンROI・使用率・追加GMV・バスケットサイズ変化・新規vs既存比・コスト率 |
| When(いつ見る) | 当日リアルタイム(9:00自動更新)/ 7日比較 / 月次サマリ の3タイムライン |
| Where(どこで見る) | Looker Studio(PC/スマホ対応)+ Slack 日次サマリ通知 |
| Why(なぜ必要か) | 翌日に効果が見えれば予算シフトが可能。月次では施策改善サイクルが遅い |
| How Much(規模) | 50万枚/月・月額1,200万円の割引コストを ROI 管理 |
| How(技術実装) | BigQuery → dbt(mart_coupon_kpi_daily)→ Looker Studio 自動更新(12時間キャッシュ) |
| How Many(目標数値) | ROI 2.5x・使用率 27%・割引コスト率 3%以内 |
| How Fast(速度要件) | ダッシュボード応答 1秒以内(mart_coupon_kpi_last30d 小テーブル参照) |
3. dbt モデル構成
-- models/marts/mart_coupon_kpi_daily.sql
{{ config(
materialized='incremental',
incremental_strategy='insert_overwrite',
partition_by={'field': 'order_date', 'data_type': 'date', 'granularity': 'day'},
cluster_by=['campaign_name', 'coupon_code']
) }}
WITH base AS (
SELECT
order_date,
coupon_code,
campaign_name,
order_id,
user_id,
net_sales,
gross_sales,
gross_sales - net_sales AS discount_amount,
-- バスケットサイズ: 注文内アイテム合計
net_sales / NULLIF(COUNT(*) OVER (PARTITION BY order_id), 0)
AS basket_size
FROM {{ ref('int_coupon_orders_joined') }}
{% if is_incremental() %}
WHERE order_date >= DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 3 DAY)
{% endif %}
)
SELECT
order_date,
coupon_code,
campaign_name,
-- ──── 効果指標(KR1: クーポン ROI) ────
SUM(net_sales) AS incremental_gmv,
SUM(discount_amount) AS discount_cost,
-- ROI = 追加GMV / 割引コスト。2.5x 以上が目標
SAFE_DIVIDE(SUM(net_sales), SUM(discount_amount)) AS coupon_roi,
-- ──── 規模指標(KR2: 使用率) ────
COUNT(DISTINCT order_id) AS order_count,
COUNT(DISTINCT user_id) AS unique_users,
AVG(basket_size) AS avg_basket_size,
-- ──── コスト管理指標(上限 3%) ────
SAFE_DIVIDE(
SUM(discount_amount),
SUM(gross_sales)
) AS discount_rate
FROM base
GROUP BY order_date, coupon_code, campaign_name
4. dbt モデル依存関係
-- dbt モデルの依存関係(DAG)
source(raw.orders) → stg_orders ─┐
source(raw.order_items) → stg_order_items ─┤ → int_coupon_orders_joined
source(raw.coupons) ───────────────────── ─┘
│
┌──────────┴──────────┐
↓ ↓
mart_coupon_kpi_daily mart_coupon_kpi_last30d
(全期間・増分更新) (30日固定窓・数MB)
│
↓
Looker Studio
(スキャン 50MB 以下)
ポイント解説
1. KPI ツリーの逆算設計
「クーポンが好調かどうか」ではなく「GMVに何%貢献したか」を起点にKPIを設計する。ノースタースター(GMV)から逆算すると、客数 × 客単価 × 効率 × 品質の4軸に自然に分解される。この順番を守ることで、指標が「レポートのための数値」ではなく「意思決定のための数値」になる。
「クーポンが好調かどうか」ではなく「GMVに何%貢献したか」を起点にKPIを設計する。ノースタースター(GMV)から逆算すると、客数 × 客単価 × 効率 × 品質の4軸に自然に分解される。この順番を守ることで、指標が「レポートのための数値」ではなく「意思決定のための数値」になる。
2. OKR の計測可能性
KR は「測定方法・現状値・目標値・期限」の4点セットで書かないと形骸化する。特に「測定方法」に
KR は「測定方法・現状値・目標値・期限」の4点セットで書かないと形骸化する。特に「測定方法」に
dbt モデル名.カラム名 を明記することで、エンジニアとビジネス側の共通言語になる。「ROIが改善した」という感覚報告から「coupon_roi が 1.8 → 2.5 になった」という事実報告に変わる。
3. 6W3H でダッシュボード設計
ダッシュボード設計では「何を見せるか(What)」より先に「誰が見るか(Who)」を決める。販促担当(クーポン別詳細)・チームリーダー(キャンペーン別ROI)・経営層(GMV貢献サマリ)で必要な粒度が異なる。3層設計が基本で、同じ指標でもドリルダウン深度を変える。
ダッシュボード設計では「何を見せるか(What)」より先に「誰が見るか(Who)」を決める。販促担当(クーポン別詳細)・チームリーダー(キャンペーン別ROI)・経営層(GMV貢献サマリ)で必要な粒度が異なる。3層設計が基本で、同じ指標でもドリルダウン深度を変える。
4. クーポン ROI の測定の落とし穴(Attribution問題)
クーポン使用者の売上増加が「クーポンがなくても買った分」を含む可能性がある。真の追加購買率を測るには A/Bテスト(クーポンあり/なしグループ)が必要。まずは「クーポン使用者 vs 非使用者のバスケットサイズ比較」から始め、A/Bテスト設計は次のステップとする。
クーポン使用者の売上増加が「クーポンがなくても買った分」を含む可能性がある。真の追加購買率を測るには A/Bテスト(クーポンあり/なしグループ)が必要。まずは「クーポン使用者 vs 非使用者のバスケットサイズ比較」から始め、A/Bテスト設計は次のステップとする。
5. 割引コスト率の上限管理
割引コスト / GMV が高すぎると利益を食いつぶす。業界標準は 2〜4%。
割引コスト / GMV が高すぎると利益を食いつぶす。業界標準は 2〜4%。
discount_rate が 3% を超えたら DataDog Monitor でアラートを設定しておくことで、キャンペーン暴走(クーポン乱用・想定外の使用爆発)を防ぐ。
実務への応用
- MOps文脈での自動化: クーポン発行システムのパラメータ(割引率・対象SKU・上限枚数)を変更するたびに、
mart_coupon_kpi_dailyが翌日朝に自動更新される仕組みを作ると、施策→効果の PDCAサイクルが翌日に完結する - BigQueryコスト連携: 前日の問題(2026-05-20 C)で設計した
mart_coupon_sales_last30d(30日固定窓・数MB)を Looker Studio に接続することで、1日100回更新されてもスキャンコスト $31/月 に抑えられる - DataDog連携:
coupon_roiが 1.5x を下回ったら Slack アラートを自動送信するモニターを設定。予算超過・効果不足の早期検知が可能 - 経営報告の自動化: Looker Studio のスケジュール配信機能で月次レポートを PDF で自動生成 → Gmail 配信。Excel 手作業ゼロへ。毎月 3〜5 時間の作業コスト削減
- Argo Workflows でのバッチ管理: dbt run を Argo Workflows で毎朝 6:00 JST に実行し、完了通知を Slack Webhook で送信。失敗時は PagerDuty へエスカレーション
今日のまとめ
KPI 設計の本質は「ノースタースター(GMV)から逆算したツリー構造」と「OKR に計測可能な形で接続すること(dbt モデル名.カラム名で測定方法を明記)」。
クーポン ROI(追加GMV / 割引コスト)を日次で可視化するだけで、月次Excelからデータドリブンな施策改善サイクルへ移行でき、PDCAが月1回 → 翌日に変わる。6W3H のダッシュボード設計で「誰が・何を・いつ見るか」を最初に定義することが、レポート品質の鍵。
クーポン ROI(追加GMV / 割引コスト)を日次で可視化するだけで、月次Excelからデータドリブンな施策改善サイクルへ移行でき、PDCAが月1回 → 翌日に変わる。6W3H のダッシュボード設計で「誰が・何を・いつ見るか」を最初に定義することが、レポート品質の鍵。