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

基本構造は次の5つの流れです。番号は処理の順で、見出しのSTEPとは一対一になりません。手順1はSTEP1、手順2はSTEP2とSTEP3、手順3の点検(QA)はSTEP5、手順4はSTEP4で説明し、手順5の出力は「月次成果テーブル」と「識別できた成果」の節で説明します。
- 店舗マスタで
store_idと外部システムIDを対応付ける - GBP・Web・予約・電話・POSの各データに
store_idを付与する - 各データの重複・欠損・期間ずれをQA(品質点検)する
- 原則として
store_id × monthに集約してからJOINする - 予約・通話・来店・売上を「識別できた成果」として同じ店舗行へ出力する
注意したいのは、経路案内や電話クリックを来店・予約へ読み替えないことです。Googleが持つ行動データと、自社側で確認できた予約・通話・来店・売上は、別の列として保持します。
7つのテーブルと「1行の粒度」を先に決める
最初に、どのデータを何単位で持つかを決めます。実装で最も避けたいのは、粒度の違う生データを店舗名だけで直接JOINし、件数や売上を二重計上することです。次の表は、統合に使う7つのテーブルについて、1行の粒度、主キー候補(各行を重複なく見分けるための列)、store_id の付与元、最低限持つ列をまとめたものです。
| テーブル | 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_id を持たせる位置です。store_master では主キー側、store_month_result では出力キーとなり、ほかの実績テーブルには各システムの店舗コードなどから store_id を付与します。store_master は単なる店舗一覧ではなく、異なるシステムのIDを同じ店舗へ変換するためのディメンションテーブルとして扱います。予約、電話、POSなどの実績テーブルは、このマスタを参照する外部キーを持つ形にします。
STEP1|社内 store_id を主キーにし、外部IDは対応表で持つ
店舗名は結合のキーにしません。店名変更、全角・半角、略称、ブランド表記、駅前・本店などの表記差で、同じ店舗が別店舗として扱われてしまうためです。
店舗IDの履歴を設計するときは、GBP自体を住所変更・閉業・新規作成・重複整理のどれで処理するかも区別しておく必要があります。GBP側の判断手順は「Googleビジネスプロフィールの移転・閉業対応」で確認できます。
社内では 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 へ正規化する
STEP2では、GBPとWebの流入データを store_id に結び付けます。どちらも店舗名ではなく、location IDやURL上の値から店舗を特定するのがポイントです。
GBPはlocation IDから store_id へ変換する
Business Profile Performance APIは、locations/{locationId} の形でロケーション(店舗)を指定して指標を取得する仕様です。取得したデータにはlocation IDを残し、店舗マスタで store_id へ変換します。
2026年6月からGoogle AnalyticsとGoogleビジネスプロフィールを直接連携できるようになりましたが、複数のBusiness Profileを連携した場合、GBP指標は合算され、個別プロフィール単位でセグメントやフィルタリングはできません。そのため、店舗別の成果テーブルでは、GA4連携で得られる合算値だけを店舗別データとして使うことはできません。

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 に対応付ける
STEP3では、自社側のデータである予約・電話・POSを store_id に対応付けます。GBPの指標とは別に、自社で確認できた成果として保持するのが前提です。
予約は「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は「同じ粒度にそろえてから」行う
STEP4では、STEP1〜3で store_id を付けたデータを、二重計上を起こさずに結合するための4つのルールを説明します。

データ統合で起きやすい失敗は、複数の明細テーブルを store_id だけで直接JOINし、行数を増幅させることです。
たとえば1店舗に同月10件の予約と20件のPOS取引がある状態で、予約明細とPOS明細を store_id + month だけで結ぶと、1対多×1対多になり、200行へ増える可能性があります。その状態で売上を合計すると二重計上になります。
この例では、予約1件に取引20件が、取引1件に予約10件が対応してしまい、組み合わせの数だけ行が増えます。同じ売上を何度も数えるため、合計が実際より大きくなります。
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 に集約する
月次成果テーブルを作る場合は、結合する前に、各データを次の同じ粒度に集約します。
- GBP:
store_id × month - Web:
store_id × month - 予約:
store_id × month - 電話:
store_id × month - POS:
store_id × month
例外は、個人や予約の単位で因果を追える場合です。そのときだけ、reservation_id や対応IDで1件ずつの記録をつなぐ結合(イベントレベルJOIN)を行います。
JOINルール4|基準表は「全店舗×全対象月」にする
月次出力では、最初に store_id × month の基準表を作り、各集計をLEFT JOINします。データがない店舗・月を行ごと消さないためです。
LEFT JOINは、基準表の行をすべて残したまま、各集計を結び付ける結合です。
ここで 0 と NULL を区別します。
0:計測できており、その月の件数が0NULL:未連携、未取得、対応不能などで値が分からない
未取得を0件に置き換えると、実績が悪い店舗と計測できていない店舗を区別できません。結合後の空欄を、一律に0で埋めないようにします。
STEP5|集計前に欠損・重複・閉店・移転をQAする
STEP4の結合ルールを守っても、マスタの誤りやデータの欠損は残ります。月次集計の前に、最低限次の9項目を点検します。
| 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月」で出力する
最終出力は、現場の担当者が店舗を比較でき、データ担当者が元データへ戻って確認できる構造にします。次の表が、1つの店舗の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 |
列は、GBPの行動から自社で識別できた予約・通話・来店・売上へと、おおむね顧客の動きの順に並べています。月次会議では、この1行の中でどこが落ちているかを見ます。表示やクリックが弱いのか、Webから予約へ進まないのか、予約後の来店率が低いのか、来店後の売上が弱いのかを分けて確認します。
KPIは同じ母集団同士で計算する
KPIは、分母と分子が同じ条件で集めた数字(たとえば、どちらもGBP/MEO経由と識別できたもの)になるように計算します。次の表は、その計算例です。
| 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店舗で、次の8項目を確認します。
- GBP location IDが正しい
store_idへ変換される - GBP→Webの流入が店舗別に識別できる
- 予約レコードへ
store_idが残る - 電話クリックと実通話を別に保持できる
- 予約→来店→POSを対応できる範囲が分かる
- 同じ月の各データをJOINしても件数・売上が増幅しない
unmappedとNULLが意図どおり残るstore_id × monthの最終行が1行だけになる
1店舗で数字が再現できたら、店舗マスタへ外部IDを追加し、同じルールで全店舗へ展開します。
まとめ|店舗IDとJOIN設計から始める
多店舗MEOの成果データを統合する場合、中心になるのはKPIの数ではなく店舗IDとJOIN設計です。
社内の store_id を主キーにし、GBP location ID、Webの店舗識別値、予約店舗コード、電話計測ID、POS店舗コードを対応付けます。各ソースは主キー重複と未マッピングを確認したうえで、原則として store_id × month に集約してから結合します。
さらに、閉店・移転・店名変更の履歴、NULLと0の違い、カスタム予約リンク、電話クリックと実通話の違いまで設計と点検に含めると、数字が並ぶだけのレポートではなく、店舗別成果を継続して比べられるデータ基盤になります。最初の一歩は、店舗マスタを作り、1店舗で store_id の対応と件数が増えないことを確認することです。
参考文献・データ元
この記事で参照した情報を確認できます。
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の仕様を確認
‹ 親記事: MEOの効果測定は何から始める?「表示・行動・来店」でつながりを追う全体像とツールの選び方
関連記事
- › MEO順位計測の設計方法|地点・検索語句・頻度を固定して店舗別に比較する
- › MEOの競合分析方法|検索地点・カテゴリ・口コミ・店舗情報を比較する
- › MEO順位変動のアラート設計|地点別順位・競合入替・GBP変更を異常検知する
- › MEO施策の実験ログを作る方法|GBP変更・順位・行動・来店を施策単位で記録
- › GBPのUTM計測方法|Web・予約・メニュー流入をGA4で確認
- › MEO順位ヒートマップの読み方・分析方法|地点グリッドで商圏・競合・弱点エリアを可視化
- › 複数店舗のMEO対策を比較|商圏・検索需要・競合密度をそろえる
- › MEOの競合入れ替わりを時系列で分析する方法|地点別Top3の変化と原因を切り分ける
- › GBP写真の効果検証|閲覧・Web・経路・予約を更新前後で比較
- › GBPカテゴリ変更の効果検証|順位・検索語句・行動を比較
- › GBPの予約・注文リンク効果|クリックから完了まで店舗別に比較
- › Googleマップ経由の電話成果を測る方法|発信・応答・予約・来店を店舗別に追う
- › Googleマップの経路検索を来店成果につなげて測る方法|ルート検索・予約・POSを店舗別に比較
- › MEO順位が急落したときの原因切り分け|計測地点・プロフィール変更・競合・口コミを順に確認
- › 多店舗でGoogleマップの成果に差が出るときの診断方法|更新・口コミ・順位・運用体制を店舗別に比較
- › 従業員規模でMEOスコアに差。300人以上の企業で最も高い結果に



