はじめに:分析結果を「スプレッドシートで見たい」現場ニーズ
BigQueryでせっかくきれいに集計しても、現場のスタッフから返ってくる言葉はだいたい決まっています。「で、それスプレッドシートでもらえますか?」。
中小ECや個人事業の現場では、BigQueryのコンソールを毎回開いてSQLを叩ける人はごく一部です。発送担当の方、経理の方、店長さん——その多くは、長年使い慣れたGoogleスプレッドシートの上でこそ数字を「読める」状態になります。フィルタをかけたり、横にメモを書いたり、別のシートと突き合わせたり。表計算ソフトは、それ自体が立派な分析の道具なんですよね。
だからデータ基盤を整えるときは、「BigQueryに集約する」だけでなく「現場が見慣れた場所まで自動で届ける」ところまでをセットで考えると、一気に喜ばれます。この記事では、BigQueryの結果をGoogleスプレッドシートに自動出力する方法を、いくつかの選択肢で比較しながら解説します。
なお、コネクタの名称やメニューの位置づけは更新が早い領域です。具体的な操作手順は、必ず最新の公式ドキュメントに従ってください。この記事では「どの方法を、どんなときに選ぶか」という考え方を中心にお伝えします。
方法の比較:3つのアプローチ
BigQueryからスプレッドシートへ流す方法は、大きく3つに分けられます。それぞれ向き不向きがあるので、まず全体像を押さえておきましょう。
1. スプレッドシートのBigQueryコネクタ(データ コネクタ)
Googleスプレッドシートには、BigQueryに直接つなぐ「データ コネクタ」が標準で用意されています。スプレッドシート側のメニューからBigQueryのデータソースを指定し、テーブルやカスタムクエリの結果をシートに取り込む仕組みです。
最大の魅力は、コードを一切書かずに設定できること。さらに「定期更新(スケジュール更新)」を設定すれば、毎朝決まった時刻に最新データへ自動で差し替えてくれます。非エンジニアの方に運用を引き継ぐなら、まずこれが第一候補です。
一方で、取り込める行数には上限があり、巨大なテーブルをそのまま全件抜くような使い方には向きません。あくまで「集計済みの、人が眺めるサイズの表」を届けるための仕組みと考えてください。
2. Apps Scriptでクエリ結果を書き込む
もう少し細かい制御がしたい場合は、Google Apps Script(GAS)からBigQueryのAPIを叩く方法があります。SQLを実行し、その結果を任意のシート・任意の範囲に書き込めるので、「複数のクエリ結果を1つのシートにまとめたい」「列の順番や見出しを整えたい」「書き込み前に古いデータを消したい」といった要望に柔軟に応えられます。
トリガー機能を使えば、毎日・毎週といった定期実行も画面上の設定だけで組めます。コードを書く必要はありますが、その分だけ自由度は高くなります。
3. スケジュール更新・定期実行の組み合わせ
上の1と2は、どちらも「定期的に走らせる」仕組みと組み合わせて初めて「自動出力」になります。コネクタならスプレッドシート側のスケジュール更新、Apps Scriptなら時間主導型トリガー、という具合です。
「とにかく手をかけずに最新を保ちたい」のがゴールなので、どの方法を選んでも、最後はこの定期実行をセットにする、と覚えておいてください。
逆に言えば、定期実行を組まずに「気づいたときに手で更新ボタンを押す」運用にしてしまうと、結局は誰も押さなくなって数字が古いまま放置されがちです。せっかく仕組みを作るなら、人の手を介さない状態まで持っていくのがコツです。
| 方法 | コード | 自由度 | 向いている場面 |
|---|---|---|---|
| BigQueryコネクタ | 不要 | 中 | 集計済みの表をそのまま定期更新したい |
| Apps Script | 必要 | 高 | 整形・複数クエリ・前処理を挟みたい |
ちなみに、最初の一歩としては迷わずコネクタから始めるのをおすすめします。コードを書かずに動く状態をまず作り、「この整形が毎回手間だな」「複数の表を1枚にまとめたいな」といった具体的な不満が出てきたタイミングで、Apps Scriptへ移行する。この順番なら、いきなりコードを書くハードルを越えずに済みますし、本当に必要な機能だけを後から足していけます。
代表的な手順
ここからは、実際の流れを2系統に分けて見ていきます。
コネクタで接続して定期更新する
コネクタを使う場合の流れは、ざっくり次のとおりです。
- スプレッドシートを開き、データソースとしてBigQueryを追加する
- 対象のGoogle Cloudプロジェクトを選び、テーブルを指定するか、カスタムクエリ(SQL)を入力する
- 取り込んだデータをシートに「抽出」して、人が読める表として配置する
- スケジュール更新を有効にして、更新の時刻と頻度(毎日・毎週など)を決める
ポイントは、ステップ2で「テーブル全件」ではなく「集計済みのクエリ結果」を指定することです。例えば、こんなSQLをカスタムクエリとして渡しておくと、シート側はいつも見やすいサマリーになります。
-- 直近30日の日次売上サマリー
SELECT
DATE(order_timestamp) AS order_date,
COUNT(DISTINCT order_id) AS orders,
SUM(amount) AS sales
FROM `myproject.shop.orders`
WHERE order_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY order_date
ORDER BY order_date
あとはスケジュール更新に任せておけば、現場の人は何も操作しなくても、毎朝シートを開くだけで最新の数字に出会えます。
カスタムクエリを使うときの小さなコツとして、列名(エイリアス)は日本語の見出しまで含めて整えておくと、現場での評判がぐっと良くなります。order_date のままより 注文日 と出ているほうが、SQLを知らない人にはやさしいですよね。届け先のことを考えて、SQLの段階から「読み手目線」で書いておくのがおすすめです。
Apps ScriptでBQクエリ→シート書き込み
もう少し作り込みたいときは、Apps Scriptです。下のコードは、BigQueryでクエリを実行し、結果を指定シートに書き出す最小例です。事前に、スクリプト側でBigQuery APIの利用を有効化しておく必要があります。
function exportBigQueryToSheet() {
const projectId = 'myproject';
const sheetName = 'daily_sales';
const query = `
SELECT
DATE(order_timestamp) AS order_date,
COUNT(DISTINCT order_id) AS orders,
SUM(amount) AS sales
FROM \`myproject.shop.orders\`
WHERE order_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY order_date
ORDER BY order_date
`;
// クエリ実行(標準SQL)
const request = { query: query, useLegacySql: false };
const queryResults = BigQuery.Jobs.query(request, projectId);
const rows = queryResults.rows || [];
const fields = queryResults.schema.fields.map(f => f.name);
// ヘッダー + データを2次元配列に整形
const data = [fields];
rows.forEach(row => {
data.push(row.f.map(cell => cell.v));
});
// シートを取得して、いったんクリアしてから書き込み
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName) || ss.insertSheet(sheetName);
sheet.clearContents();
sheet.getRange(1, 1, data.length, fields.length).setValues(data);
}
このスクリプトを、Apps Scriptの時間主導型トリガーで「毎日午前7時」などに実行するよう設定すれば、コネクタと同じく自動出力が完成します。clearContents() でいったん消してから書き直しているので、行数が日によって増減してもゴミが残りません。
複数のクエリ結果を別々のシートにまとめたり、書き込んだあとに通知を飛ばしたりと、ここから先は自由に拡張できます。
注意点としては、Apps Scriptには1回あたりの実行時間の上限があります。重いクエリを何本も直列で回すと途中で打ち切られることがあるので、その場合は実行を分割するか、そもそもBigQuery側で集計を済ませて結果を軽くしておきましょう。「重い処理はBigQueryに寄せる」という発想は、コネクタでもApps Scriptでも共通して効いてきます。
注意:権限共有・更新頻度とコスト・大きすぎるデータ
便利な仕組みですが、運用に入る前に必ず押さえておきたい注意点が3つあります。
権限の共有に注意。 コネクタやApps Scriptは、設定した人(または実行アカウント)の権限でBigQueryにアクセスします。スプレッドシートを共有すると、データそのものは見えても、裏側のBigQueryへの直接アクセス権までは渡りません。逆に、実行アカウントが強い権限を持っている場合、出力されたシートを通じて見せたくないデータまで広く共有してしまわないか、出力するクエリの内容と共有範囲を必ず確認してください。
更新頻度とコストはトレードオフ。 BigQueryはスキャン量に応じた従量課金です。更新のたびにクエリが走るので、「5分おきに自動更新」のような高頻度設定は、必要性が薄いわりにコストとスキャン量を押し上げます。多くの現場では「1日1回・朝に更新」で十分です。集計済みの軽いクエリを、必要な頻度だけ走らせるのが基本方針になります。
大きすぎるデータは流し込まない。 スプレッドシートには扱えるセル数・行数の上限があり、そもそも数十万行を人が目で追うことはありません。生ログをそのまま全件出すのではなく、BigQuery側で集計・絞り込みを済ませた「読めるサイズ」にしてから渡すのが鉄則です。重い処理はBigQueryに任せ、スプレッドシートは表示と共有に専念させましょう。
実際の現場でよくある使い方
最後に、中小ECや個人事業の現場でよく作る出力パターンを3つ紹介します。どれも「集計済みの軽い表を、毎朝1回シートに届ける」という基本形の応用です。
日次の売上・受注サマリー
いちばん定番なのが、前日までの売上・受注件数・客単価を日別に並べた表です。経理や店長さんが毎朝ざっと眺める用途で、グラフを足さなくても数字の並びだけで十分役に立ちます。先ほどのSQL例がそのまま使えます。
在庫・発送ステータスの一覧
発送担当の方向けには、「未発送の注文一覧」や「残在庫が少ない商品リスト」を出しておくと喜ばれます。この手の表は、BigQueryで条件を絞り込んでから渡すのがポイントです。全件ではなく「対応が必要な行だけ」が並んでいると、現場はそのまま作業に使えます。
広告・流入のサマリー
マーケ寄りの数字をまとめて1枚にしておくのも便利です。媒体別の費用・売上・ROASあたりを日別に並べておけば、毎朝の予算判断の材料になります。ただし、こうした「眺めて判断する」用途であれば、グラフ表現が得意なBI側に寄せたほうが見やすいこともあります。スプレッドシートで配るか、ダッシュボードで配るかは、受け手が何をしたいかで選び分けてください。
いずれの場合も、「誰が、いつ、何のために見るか」を先に決めてから出力内容を設計すると、無駄なく刺さる1枚になります。逆に「とりあえず全部出しておこう」とすると、情報が多すぎて結局誰も読まない表になりがちなので注意です。
まとめ
BigQueryの結果をGoogleスプレッドシートへ自動出力する方法を、3つのアプローチで見てきました。あらためて整理すると、選び方はシンプルです。
- コードを書かずに済ませたいなら、まずBigQueryコネクタ+スケジュール更新
- 整形や前処理、複数クエリのまとめが必要なら、Apps Script+トリガー
- どちらを選んでも、集計済みの軽いクエリを必要な頻度だけ走らせるのが基本
データ基盤の価値は、難しいSQLを書けることではなく、必要な人が必要な数字に毎日ストレスなく出会える状態をつくることにあります。BigQueryで重い処理を引き受け、現場には見慣れたスプレッドシートで届ける——この役割分担ができると、データ共有はぐっとスムーズになります。
BigQueryを社内の分析にもっと活かす話はMCP×Claude CodeでBigQueryを社内分析する記事で、定期レポートをPDFで配る方法はLooker StudioのPDF自動メール送信の記事でそれぞれ掘り下げています。あわせて読んでみてください。