asopi tech
asopi techIndie Developer

Asopitech With · 表計算

Google Sheets with Alopex DB

Google Sheetsは、数式とピボットテーブルでデータを集計する表計算です。Alopex DBで同じものを作るとしたら…?

更新: 2026/10/12

どんなサービスか

Google Sheetsのような表計算は、セルに数式を書き、ピボットテーブルとグラフでデータを集計し、複数の人が同じシートを同時に編集します。日々の記録をためて、あとから集計する道具として使われます。扱うデータは、行として増えていく記録と、それを集計した結果です。

データの置き場所

  • カラムナーテーブル:売上、作業時間、アクセスのような、行が増えていく記録をカラムナーテーブルに持ちます。列ごとに圧縮して保存し、集計では必要な列だけを読みます。
  • 取り込み:CSVやParquetのファイルはCOPYで、アプリからの記録はHTTPの取り込みで、まとめて入れます。
  • SQLの集計:ピボットの代わりに、GROUP BY とウィンドウ関数で、月別、担当別、前月比を出します。結果はビューにして、何度でも同じ形で読めます。

配置の形

分析する人は、PythonやDataFrameのクライアントから、同じデータを読みます。ノートブックでAlopex DBを組み込みで開き、集計の結果をそのままDataFrameで扱います。チームで使う記録は、Alopex DBのサーバーに置き、取り込みはHTTP、分析はPythonから行います。

Alopex DBが合う理由

記録が増えるほど、表計算は重くなります。Alopex DBのカラムナーテーブルは、増え続ける記録をSQLとDataFrameで集計するための置き場所です。行のテーブルと同じデータベースに入るので、マスターのテーブルとの結合もSQLのままです。

コードで見る

増えていく記録を持ち、担当別・月別の合計と前月比を、ピボットの代わりにSQLで出します。集計の中心だけを取り出したコードです。

import alopex

db = alopex.Database.open("sheets.alopex")

# 増えていく記録(売上)をためる
db.execute_sql("""
    CREATE TABLE IF NOT EXISTS sales (
        month TEXT,
        dept TEXT,
        amount INTEGER
    )
""")

records = [
    ("2026-07", "東京", 100), ("2026-07", "大阪", 80),
    ("2026-08", "東京", 150), ("2026-08", "大阪", 90),
    ("2026-09", "東京", 120), ("2026-09", "大阪", 110),
]
for month, dept, amount in records:
    db.execute_sql("INSERT INTO sales (month, dept, amount) VALUES (?, ?, ?)", [month, dept, amount])

# 担当別・月別の合計と、前月比(担当ごとの LAG)を出す
rows = db.execute_sql("""
    WITH monthly AS (
        SELECT month, dept, SUM(amount) AS total
        FROM sales
        GROUP BY month, dept
    )
    SELECT month, dept, total,
           total - LAG(total) OVER (PARTITION BY dept ORDER BY month) AS mom
    FROM monthly
    ORDER BY dept, month
""")

for row in rows:
    print(row["dept"], row["month"], row["total"], "前月比", row["mom"])

GROUP BY で担当別・月別にまとめ、ウィンドウ関数で担当ごとの前月比を出します。ピボットをSQLに置き換えられ、結果はビューにして何度でも同じ形で読めます。

カラムナーテーブル、SQLの集計、PythonのDataFrameがそろうAlopex DBは、記録と集計の仕組みにおすすめです。クイックスタートから始められます。

関連リンク