MEOの成果を表示回数や順位だけで見ても、店舗別の予約・来店・売上までは分かりません。多店舗運営で難しいのは、Googleビジネスプロフィール(GBP)、Web、予約、電話、POSが、それぞれ別の店舗識別子を持っていることです。
この記事ではMEOのKPI全体像ではなく、共通の store_id を軸に各システムのデータを正規化し、JOINし、月次の店舗別成果テーブルまで作る実装方法に絞って解説します。MEO効果測定の指標全体やツール選定から確認したい場合は、先に「MEOの効果測定は何から始める?」を確認してください。
結論|先に「店舗マスタ」と「出力粒度」を固定する
多店舗MEOのデータ統合では、最初からGBP・予約・電話・POSを直接つなげません。先に社内共通の store_id を発行し、各システムの店舗IDとの対応表を作ります。そのうえで各データを同じ粒度へそろえてから結合します。

基本構造は次のとおりです。
- 店舗マスタで
store_idと外部システムIDを対応付ける - GBP・Web・予約・電話・POSの各データに
store_idを付与する - 各データの重複・欠損・期間ずれをQAする
- 原則として
store_id × monthに集約してからJOINする - 予約・通話・来店・売上を「識別できた成果」として同じ店舗行へ出力する
ここで重要なのは、経路案内や電話クリックを来店・予約へ読み替えることではありません。Googleが持つ行動データと、自社側で確認できた予約・通話・来店・売上は別の列として保持します。
最小データモデルと列定義
最初に、どのデータを何単位で持つかを決めます。実装で最も避けたいのは、粒度の違う生データを店舗名だけで直接JOINし、件数や売上を二重計上することです。
| テーブル | 1行の粒度 | 主キー候補 | store_id の位置 |
最低限持つ列 |
|---|---|---|---|---|
store_master |
1店舗×有効期間 | store_id + valid_from |
主キー側 | store_id、店舗名、各外部ID、valid_from、valid_to、status |
gbp_daily |
1店舗×1日 | gbp_location_id + date |
店舗マスタから付与 | date、location_id、表示・Webクリック・通話クリック・経路案内等 |
web_session |
1セッションまたは集計済み日次 | session_id等 | UTM・店舗ページから付与 | date、source、medium、campaign、店舗識別値、CV |
reservation |
1予約 | reservation_id |
予約店舗コードから付与 | reservation_id、予約日時、予約状態、流入元、来店状態 |
call |
1着信・1通話 | call_id |
電話計測IDから付与 | call_id、日時、応答有無、予約成立有無、流入識別 |
pos_transaction |
1取引 | transaction_id |
POS店舗コードから付与 | transaction_id、日時、売上、粗利、対応する予約ID等 |
store_month_result |
1店舗×1月 | store_id + month |
出力キー | GBP行動、予約、通話、来店、識別売上、QA列 |
store_master は単なる店舗一覧ではなく、異なるシステムのIDを同じ店舗へ変換するためのディメンションテーブルとして扱います。予約、電話、POSなどの実績テーブルは、このマスタを参照する外部キーを持つ形にします。
STEP1|社内 store_id を主キーにし、外部IDは対応表で持つ
店舗名はJOINキーにしません。店名変更、全角・半角、略称、ブランド表記、駅前・本店などの表記差で別店舗として扱われるためです。
店舗IDの履歴設計とあわせて、GBP自体を住所変更・閉業・新規作成・重複整理のどれで処理するかも切り分ける必要があります。GBP側の判断手順は[Googleビジネスプロフィールの移転・閉業対応](https://rebranding.co.jp/media/google-business-profile-relocation-closure/)で確認できます。
社内では store_001 のような固定IDを発行し、各システムの識別子を対応付けます。
| 項目 | 例 | 用途 |
|---|---|---|
store_id |
store_001 | 社内の共通主キー |
| 店舗表示名 | 新宿駅前店 | レポート表示用。JOINには使わない |
| GBP location ID | 1234567890 | GBP Performance APIとの対応 |
| GBP store code | BRAND001 | GBP管理上の店舗コード |
| 店舗ページ | /shop/shinjuku/ | Web流入先の対応 |
| 予約店舗コード | SHJ01 | 予約データの外部キー |
| 電話計測ID | CALL_SHJ01 | 電話データの外部キー |
| POS店舗コード | 1001 | POSデータの外部キー |
valid_from |
2026-01-01 | 対応開始日 |
valid_to |
9999-12-31 | 対応終了日 |
status |
active | active / closed / merged 等 |

各システムのID自体を同じ値へ変更する必要はありません。重要なのは、どの外部IDが、どの期間に、どの store_id を指していたかを1か所で管理することです。
店名変更では store_id を変えない
店舗名だけが変わった場合は、同一店舗の履歴として扱い、原則として store_id は維持します。名称は属性として更新し、過去データのキーは変えません。
移転・閉店は「社内ID」と「GBP側ID」を分けて考える
移転では、社内で同一店舗として継続管理するのか、新店舗として別管理するのかを先に決めます。Google側のstore codeやlocation IDの扱いは運用条件で変わるため、GBPの識別子を社内の永久主キーにはしません。
同一店舗として継続する場合でも、外部IDの変更履歴は valid_from / valid_to で管理します。閉店済みの store_id は再利用せず、過去データを別店舗へ付け替えないようにします。
STEP2|GBP・Webの流入キーを store_id へ正規化する
GBPはlocation IDから store_id へ変換する
Business Profile Performance APIは、特定ロケーションを locations/{locationId} で指定して指標を取得する設計です。取得したデータにはlocation IDを残し、店舗マスタで store_id へ変換します。
2026年6月からGoogle AnalyticsとGoogleビジネスプロフィールを直接連携できるようになりましたが、複数のBusiness Profileを連携した場合、GBP指標は合算され、個別プロフィール単位でセグメントやフィルタリングはできません。したがって、多店舗の店舗別成果テーブルでは、GA4連携の合算値だけを店舗別JOINの入力には使えません。

GA4連携は全体傾向の確認に使い、店舗別のGBPデータはlocation IDを基準に別途取得・対応付けるのが安全です。
WebはUTMまたは店舗ページから store_id を復元する
GBPからWebへ送るURLでは、全店舗で同じ命名規則を使います。
utm_source=google&utm_medium=organic&utm_campaign=gbp&utm_content=store_001
Google Analyticsでは utm_source、utm_medium、utm_campaign の利用が案内されており、UTM値は大文字・小文字を区別します。Google と google が混在すると別値になるため、小文字固定などのルールを先に決めます。
utm_content を店舗識別に使う例は実装しやすい一方、既存のUTM設計がある場合は無理に上書きしません。店舗別ランディングページ、独自パラメータ、予約システムへ引き継ぐ店舗コードなど、最終的に store_id へ一意に変換できる列を1つ確保します。
STEP3|予約・電話・POSを store_id に対応付ける
予約は「GBP上の予約数」と「自社予約」を別列にする
予約システムでは、最低限 reservation_id、store_id、予約日時、予約状態、流入元を持たせます。
Google公式では、カスタム予約リンクのパフォーマンスデータはGBP上では提供されません。したがって、自社で追加した予約リンクを使う場合は、GBPの「予約」指標に出ることを前提にせず、予約システム側で流入元と店舗IDを保持します。
予約サービスがUTMを保持できない場合は、GBP専用の店舗ページを経由させる、店舗別URLを用意する、予約データへ専用流入コードを保存するなど、実装可能な方法へ切り替えます。
電話は「クリック」「着信」「予約成立」を別レコードで扱う
GBPの電話指標は、プロフィール上の電話ボタンがクリックされた回数であり、実際の通話成立や予約成立を示す数字ではありません。また、Googleビジネスプロフィールの通話履歴機能は2024年7月31日に終了しています。
そのため、電話成果は次の3段階を分けます。
| 段階 | 取得元 | 推奨列 |
|---|---|---|
| GBP電話クリック | GBP | gbp_call_clicks |
| 実着信・応答 | 電話システム | call_id、answered、store_id |
| 予約・問い合わせ成立 | CRM・予約 | call_id、reservation_id、converted |
コールトラッキングを使わない場合は、受付時の流入元確認を残す方法もあります。ただし、その場合は「MEO経由と申告された電話予約」など、識別方法が分かるKPI名にします。
POSは店舗コードを store_id へ変換し、取引IDを重複させない
POSでは transaction_id、POS店舗コード、取引日時、売上を保持し、店舗マスタ経由で store_id を付与します。
予約IDや会員IDと安全に対応付けられる場合は、予約→来店→売上まで追えます。ただし、マーケティング集計表へ氏名や電話番号をそのまま持ち込む必要はありません。分析用IDと成果列へ絞ります。
STEP4|JOINは「同じ粒度にそろえてから」行う

データ統合で最も多い事故は、複数の明細テーブルを store_id だけで直接JOINし、行数を増幅させることです。
たとえば1店舗に同月10件の予約と20件のPOS取引がある状態で、予約明細とPOS明細を store_id + month だけで結ぶと、1対多×1対多になり、200行へ増える可能性があります。その状態で売上を合計すると二重計上になります。
JOINルール1|まず各システム内で主キー重複をなくす
- 予約:
reservation_idが一意 - 電話:
call_idが一意 - POS:
transaction_idが一意 - GBP日次:
gbp_location_id + dateが一意 - 店舗マスタ:同じ有効期間内で外部IDが複数の
store_idを指さない
同じ主キーが複数行ある場合は、JOIN前に原因を確認します。後段で DISTINCT をかけて隠すのではなく、重複発生元を直します。
JOINルール2|外部IDを先に store_id へ正規化する
予約店舗コード、電話ID、POS店舗コード、GBP location IDを、それぞれ店舗マスタで store_id へ変換します。変換できなかった行は削除せず、unmapped として残します。
JOINルール3|月次レポートでは各ソースを store_id × month に集約する
月次成果テーブルを作るなら、JOIN前に各データを同じ粒度へ集約します。
- GBP:
store_id × month - Web:
store_id × month - 予約:
store_id × month - 電話:
store_id × month - POS:
store_id × month
個人・予約単位で因果を追える場合だけ、reservation_id や対応IDでイベントレベルJOINを行います。
JOINルール4|基準表は「全店舗×全対象月」にする
月次出力では、最初に store_id × month の基準表を作り、各集計をLEFT JOINします。データがない店舗・月を行ごと消さないためです。
ここで 0 と NULL を区別します。
0:計測できており、その月の件数が0NULL:未連携、未取得、対応不能などで値が分からない
未取得を0件に置き換えると、実績が悪い店舗と計測できていない店舗を区別できません。
STEP5|欠損・重複・閉店・移転をQAする
月次集計の前に、最低限次のQAを通します。
| QA項目 | 検出条件 | 対応 |
|---|---|---|
store_id 重複 |
同じ内部IDが別店舗として登録 | マスタ修正 |
| 外部ID重複 | 同一期間に同じ外部IDが複数store_idへ紐付く | 対応表を修正 |
| 未マッピング | 外部IDからstore_idへ変換できない | unmapped として件数を出す |
| 主キー重複 | reservation_id / call_id / transaction_id が重複 | 発生元確認。単純削除しない |
| JOIN後行数増幅 | JOIN前より明細行が不自然に増える | 粒度・結合キーを見直す |
| 予約状態欠損 | キャンセル・来店済みが区別できない | unknown を別集計 |
| 閉店後データ | valid_to 後にも外部データが発生 |
マッピング・プロフィール状態を確認 |
| 移転前後混在 | 旧外部IDと新外部IDが同月に混在 | 有効期間で振り分ける |
| タイムゾーン差 | 月末データが翌月へずれる | 集計基準タイムゾーンを統一 |
複数GBPプロフィールが同じ店舗を指す場合は自動合算しない
重複プロフィールや移転途中などで、複数のGBP location IDが同じ store_id に候補として紐付くことがあります。この場合は、単純に合算する前に、同じ実店舗の有効プロフィールなのか、重複・旧プロフィールなのかを確認します。
移転履歴は期間で管理する
たとえば、2026年6月までは旧location ID、7月から新location IDを使う場合、店舗マスタの対応を期間で分けます。過去データを新IDへ上書きしないことで、月次推移が壊れにくくなります。
月次成果テーブルは「1店舗×1月」で出力する
最終出力は、担当者が店舗比較でき、かつデータ担当者が元データへ戻れる構造にします。
| 列 | 内容 |
|---|---|
month |
集計月 |
store_id |
社内共通店舗ID |
store_name |
表示用店舗名 |
gbp_website_clicks |
GBPのWebクリック |
gbp_call_clicks |
GBPの電話クリック |
gbp_directions |
GBPの経路案内 |
gbp_bookings |
Google側で取得できた予約 |
web_sessions_gbp |
GBP経由と識別できたWebセッション |
reservations_identified |
GBP/MEO経由と識別できた予約 |
calls_answered_identified |
MEO経由と識別できた実通話 |
phone_reservations_identified |
電話から成立した識別予約 |
visits_identified |
来店済みとして確認できた件数 |
revenue_identified |
MEO経由と識別できた売上 |
unmapped_records |
店舗IDへ変換できなかったレコード数 |
qa_status |
OK / WARN / ERROR |
月次会議で見るのは、この1行の中でどこが落ちているかです。表示やクリックが弱いのか、Webから予約へ進まないのか、予約後の来店率が低いのか、来店後の売上が弱いのかを切り分けます。
KPIは同じ母集団同士で計算する
| KPI | 計算例 |
|---|---|
| GBP経由Web予約率 | reservations_identified ÷ web_sessions_gbp |
| 予約来店率 | visits_identified ÷ reservations_identified |
| 電話予約化率 | phone_reservations_identified ÷ calls_answered_identified |
| 識別売上 | revenue_identified の合計 |
GBPの電話クリックを分母にし、電話システムの全予約数を分子にするなど、取得範囲の違う数字同士は割りません。
「識別できた成果」と「MEOが生んだ成果」は分ける
revenue_identified は、MEO経由と識別できた売上であり、MEO施策だけがその売上を生んだと証明する数字ではありません。検索、SNS、広告、口コミ、指名検索など複数接点がある顧客では、最後に観測できた流入元だけへ成果を寄せると貢献度を誤認する可能性があります。
そのため、月次成果テーブルでは少なくとも次を分けます。
- MEO経由と識別できた成果
- 流入元不明の成果
- 全店舗売上
- 計測できなかった・マッピングできなかった件数
「追跡できない成果を0にしない」ことが、店舗比較の信頼性を保つうえで重要です。
実装は1店舗で接続テストしてから全店へ広げる
最初から全店舗を接続すると、店舗コードの表記揺れや予約・電話・POSの仕様差が同時に発生し、原因を切り分けにくくなります。
まず1店舗で次を確認します。
- GBP location IDが正しい
store_idへ変換される - GBP→Webの流入が店舗別に識別できる
- 予約レコードへ
store_idが残る - 電話クリックと実通話を別に保持できる
- 予約→来店→POSを対応できる範囲が分かる
- 同じ月の各データをJOINしても件数・売上が増幅しない
unmappedとNULLが意図どおり残るstore_id × monthの最終行が1行だけになる
1店舗で数字が再現できたら、店舗マスタへ外部IDを追加し、同じルールで全店舗へ展開します。
まとめ
多店舗MEOの成果データを統合する場合、中心になるのはKPIの数ではなく店舗IDとJOIN設計です。
社内の store_id を主キーにし、GBP location ID、Webの店舗識別値、予約店舗コード、電話計測ID、POS店舗コードを対応付けます。各ソースは主キー重複と未マッピングを確認したうえで、原則として store_id × month に集約してから結合します。
さらに、閉店・移転・店名変更の履歴、NULLと0の違い、カスタム予約リンク、電話クリックと実通話の違いまでQAに含めることで、「数字が並んでいるだけのレポート」ではなく、店舗別成果を継続比較できるデータ基盤になります。
参考文献・データ元
Google Analytics Help「What’s new in Google Analytics」
2026年6月8日のGoogle Business Profile直接連携、主要GBP指標、6か月のデータ利用範囲の確認に使用。
Google Analytics更新情報を確認
Google Analytics Help「Connect Google Business Profile (GBP) to Google Analytics」
複数プロフィール連携時にGBP指標が合算され、個別プロフィール単位でセグメント・フィルタリングできない制約の確認に使用。
GBPとGA4の連携仕様を確認
Google Analytics Help「URL builders: Collect campaign data with custom URLs」
UTMパラメータの推奨構成と、大文字・小文字を区別する命名ルールの確認に使用。
Google公式UTMガイドを確認
Google Business Profile Help「Understand your Business Profile performance & insights」
GBP上で確認できる通話・経路案内等のパフォーマンス指標の定義確認に使用。
Business Profile performanceを確認
Google Business Profile Help「Set up bookings through a provider」
カスタム予約リンクでは予約パフォーマンスデータが提供されないことの確認に使用。
予約パフォーマンス仕様を確認
Google Business Profile Help「Changes to Google Business Profile chat and call history」
2024年7月31日にBusiness Profileの通話履歴機能が終了したことの確認に使用。
通話履歴機能の変更を確認
Google for Developers「Business Profile Performance API」
locations/{locationId} を指定したロケーション単位のパフォーマンスデータ取得仕様の確認に使用。
Business Profile Performance APIを確認
Google Business Profile Help「Add & manage Business Profile store codes for bulk uploads」
GBPのstore codeがロケーション管理用の一意識別子であることを確認し、社内の永久主キーとは分離して設計するために使用。
GBP store codeの仕様を確認