本文へ移動
マーケティングSQL 更新日: 2026年5月2日 約15分で読めます

相関係数をSQLで計算する方法|広告費と売上の関係を分析するクエリ


「広告を増やすと売上が上がる」を証明できるか

「先月広告費を増やしたら売上が上がりました」という報告は、本当に広告の効果を示しているのだろうか。季節要因かもしれないし、たまたま新商品が当たったのかもしれない。

2つの数値の関係を定量化する手法が相関係数だ。広告費と売上の間にどれだけ強い関係があるかを -1 から +1 の数値で表す。

  • +1 に近い :広告費が増えると売上も増える強い正の関係
  • 0 に近い :広告費と売上は無関係
  • -1 に近い :広告費が増えると売上が下がる逆の関係(稀だが存在する)

Python や Excel で簡単に計算できるが、データが Treasure Data にあるとき、わざわざ Python に持ち出さなくても SQL だけで計算できる。この記事ではピアソン相関係数の計算式を SQL に落とし込む方法を解説する。


ピアソン相関係数の計算式

ピアソン相関係数 r の公式は次の通りだ。

r = Σ(xi - x̄)(yi - ȳ) / √[Σ(xi - x̄)² × Σ(yi - ȳ)²]
  • xi :X の各値(例:各月の広告費)
  • :X の平均値
  • yi :Y の各値(例:各月の売上)
  • ȳ :Y の平均値

分子は「XとYが平均からどちらも同じ方向にずれているか」を表し、分母は「XとYそれぞれのばらつきの大きさ」で正規化する。

SQL では次の等価な式で計算するとシンプルになる。

r = (n × Σ(xi × yi) - Σxi × Σyi)
  / √[(n × Σxi² - (Σxi)²) × (n × Σyi² - (Σyi)²)]

この形にすると、SUMCOUNT だけで計算できる。


使用するテーブル

-- monthly_ad_sales(月次広告費・売上テーブル)
-- sales_month   : 集計月(DATE型)
-- ad_spend      : 広告費(円)
-- total_sales   : 売上金額(円)
-- channel       : 広告チャネル('search', 'display', 'social' など)
sales_monthchannelad_spendtotal_sales
2024-01-01search1,200,00018,400,000
2024-02-01search980,00015,200,000
2024-03-01search1,400,00021,800,000
2024-04-01search1,100,00016,900,000

STEP 1 ― 相関係数を計算するコア式

-- STEP1: 広告費と売上の相関係数を計算する

SELECT
    channel,
    COUNT(*)                              AS n,
    ROUND(AVG(ad_spend), 0)              AS avg_ad_spend,
    ROUND(AVG(total_sales), 0)           AS avg_total_sales,

    -- ピアソン相関係数
    ROUND(
        (
            COUNT(*) * SUM(ad_spend * total_sales)
            - SUM(ad_spend) * SUM(total_sales)
        )
        / NULLIF(
            SQRT(
                (COUNT(*) * SUM(ad_spend * ad_spend) - SUM(ad_spend) * SUM(ad_spend))
                *
                (COUNT(*) * SUM(total_sales * total_sales) - SUM(total_sales) * SUM(total_sales))
            )
        , 0)
    , 4)  AS pearson_r
FROM monthly_ad_sales
GROUP BY channel
ORDER BY pearson_r DESC;

出力イメージ

channelnavg_ad_spendavg_total_salespearson_r
search121,180,00018,200,0000.8841
social12840,00014,600,0000.7234
display12620,00011,800,0000.3142

検索広告(search)は相関係数 0.88 と強い正の相関がある。ディスプレイ広告(display)は 0.31 と弱い相関だ。「search の予算を増やして display を削減する」という意思決定に、この数字が根拠を与える。

NULLIF によるゼロ除算ガード
分母の SQRT の中が 0 になる(全データが同じ値)場合にゼロ除算が起きる。NULLIF(..., 0) で保護すると NULL が返り、エラーを防げる。


STEP 2 ― CORR() 関数が使えるエンジンでの実装

Presto(Treasure Data)や BigQuery では CORR() 関数が用意されており、ピアソン相関係数を1行で計算できる。

-- STEP2: CORR() 関数を使った実装(Presto / BigQuery)

SELECT
    channel,
    COUNT(*)                              AS n,
    ROUND(CORR(ad_spend, total_sales), 4) AS pearson_r
FROM monthly_ad_sales
GROUP BY channel
ORDER BY pearson_r DESC;

結果は STEP1 と同じになる。CORR() が使えるエンジンではこちらが断然シンプルだ。MySQL にはこの関数がないため、STEP1 の手動計算が必要になる。


STEP 3 ― 相関係数の解釈ガイドと有意性の補足

相関係数の大きさだけで「強い相関がある」と断言するのは危険だ。サンプル数(月数)が少ないほど、偶然の相関が大きく見える。

-- STEP3: 相関係数にサンプル数と解釈ラベルを付与する

WITH correlation AS (
    SELECT
        channel,
        COUNT(*)                              AS n,
        ROUND(CORR(ad_spend, total_sales), 4) AS pearson_r
    FROM monthly_ad_sales
    GROUP BY channel
)
SELECT
    channel,
    n,
    pearson_r,

    -- 相関の強さをラベルで表示
    CASE
        WHEN ABS(pearson_r) >= 0.8  THEN '強い相関'
        WHEN ABS(pearson_r) >= 0.6  THEN '中程度の相関'
        WHEN ABS(pearson_r) >= 0.4  THEN '弱い相関'
        WHEN ABS(pearson_r) >= 0.2  THEN 'ごく弱い相関'
        ELSE                             'ほぼ無相関'
    END  AS correlation_label,

    -- 方向性
    CASE
        WHEN pearson_r > 0 THEN '正の相関(広告費↑→売上↑)'
        WHEN pearson_r < 0 THEN '負の相関(広告費↑→売上↓)'
        ELSE                    '無相関'
    END  AS direction,

    -- サンプル数の警告
    CASE
        WHEN n < 6  THEN '⚠ サンプル数が少なく信頼性が低い'
        WHEN n < 12 THEN '△ サンプル数がやや少ない'
        ELSE             '○ サンプル数は十分'
    END  AS sample_warning
FROM correlation
ORDER BY ABS(pearson_r) DESC;

出力イメージ

channelnpearson_rcorrelation_labeldirectionsample_warning
search120.8841強い相関正の相関(広告費↑→売上↑)○ サンプル数は十分
social120.7234中程度の相関正の相関(広告費↑→売上↑)○ サンプル数は十分
display120.3142弱い相関正の相関(広告費↑→売上↑)○ サンプル数は十分

STEP 4 ― 月別の散布図データを出す

相関係数は1つの数値だが、実際の点の分布(散布図)を見ることも重要だ。外れ値が1点あるだけで相関係数が大きく動くことがある。BIツールへの入力用に散布図データをSQLで出力する。

-- STEP4: 散布図用データの出力(標準化も行う)

WITH stats AS (
    SELECT
        channel,
        AVG(ad_spend)     AS avg_x,
        STDDEV(ad_spend)  AS std_x,
        AVG(total_sales)  AS avg_y,
        STDDEV(total_sales) AS std_y
    FROM monthly_ad_sales
    GROUP BY channel
)
SELECT
    m.sales_month,
    m.channel,
    m.ad_spend,
    m.total_sales,

    -- 標準化(Zスコア):どちらの変数も平均0・標準偏差1に変換
    ROUND((m.ad_spend    - s.avg_x) / NULLIF(s.std_x, 0), 3)  AS ad_spend_z,
    ROUND((m.total_sales - s.avg_y) / NULLIF(s.std_y, 0), 3)  AS total_sales_z

FROM monthly_ad_sales  m
JOIN stats             s  ON m.channel = s.channel
ORDER BY m.channel, m.sales_month;

標準化(Zスコア変換)することで、広告費と売上という単位の異なる2変数を同じスケールで比較できる。Zスコアで散布図を描くと「どの月が外れ値か」が視覚的に分かりやすくなる。


応用:チャネル別の月次相関係数の推移

相関係数は期間全体の1点だが、「最近の半年と過去の半年で相関が変化したか」を比較することで、施策効果の変化を検知できる。

-- 前半6ヶ月と後半6ヶ月の相関係数を比較する

WITH period_labels AS (
    SELECT
        *,
        CASE
            WHEN sales_month < DATE '2024-07-01' THEN '前半(1〜6月)'
            ELSE                                      '後半(7〜12月)'
        END  AS period
    FROM monthly_ad_sales
    WHERE sales_month >= DATE '2024-01-01'
    AND   sales_month <  DATE '2025-01-01'
)
SELECT
    channel,
    period,
    COUNT(*)                              AS n,
    ROUND(CORR(ad_spend, total_sales), 4) AS pearson_r
FROM period_labels
GROUP BY channel, period
ORDER BY channel, period;

出力イメージ

channelperiodnpearson_r
search前半(1〜6月)60.9124
search後半(7〜12月)60.7841
social前半(1〜6月)60.6234
social後半(7〜12月)60.8124

search は後半に相関が少し下がり(0.91 → 0.78)、social は後半に相関が上がった(0.62 → 0.81)。social 広告の施策改善が功を奏した可能性がある、という仮説が立てられる。


相関係数を使うときの3つの注意点

注意1:相関は因果ではない

pearson_r = 0.88 は「searchの広告費が増えると売上が増える傾向がある」ことを示すが、「広告費を増やしたから売上が増えた」という因果関係を証明するものではない。売上が増えた時期に広告費も増やす運用をしていたら、逆因果(売上 → 広告費)の可能性もある。

注意2:外れ値に敏感

1つの外れ値が相関係数を大きく動かす。必ず散布図(STEP4のデータ)と合わせて確認し、外れ値の月を除外した場合の相関係数も計算しておくと信頼性が上がる。

注意3:サンプル数が少ない場合は信頼できない

月次データで12ヶ月分あれば最低限だが、6ヶ月以下では偶然の相関が大きく見える。より多くの観測期間があるほど、相関係数の信頼性は上がる。


実務での運用ヒント

① 相関係数ダッシュボードを月次で自動更新する

「直近12ヶ月のチャネル別広告費×売上相関係数」をBIツールに繋げて月次自動更新にすると、広告効果のモニタリングが自動化できる。相関係数が0.6を下回ったチャネルに自動アラートを出す設計にすることも可能だ。

② 広告費以外の変数との相関も試す

同じクエリで「メルマガ配信数と売上」「気温と売上」「競合の広告費と自社売上」など、さまざまな変数の組み合わせを試すことができる。意外な変数との高い相関が分析の出発点になることがある。

③ ラグ(遅延)相関を考慮する

広告の効果は即日ではなく1〜2週間後に売上として現れることがある。「今月の広告費と翌月の売上」の相関を計算するには、LAG(またはLEAD)で時系列をずらしたデータに対して相関を計算する。No.2(購買間隔分析)と組み合わせた応用だ。


まとめ

SQL だけで相関係数を計算する方法を振り返る。

  1. CORR(x, y) 関数が使えるエンジン(Presto・BigQuery)ではこれを使う
  2. 使えないエンジン(MySQL)では COUNT・SUM・SQRT を組み合わせた手動計算式を使う
  3. 相関係数だけでなくサンプル数・強さのラベル・方向性を一緒に出す
  4. 散布図データも出力して外れ値を目視で確認する
  5. 期間を分けて比較することで「相関の変化」を検知できる

「広告を増やすと売上が上がる」を勘ではなく数値で語れるようになることが、このクエリが提供する価値だ。意思決定の根拠を SQL で作り、会議室に持ち込もう。


次のアクション

SQLやデータ活用を、手元で試しながら理解する

記事で読んだ考え方を、SQL練習場や関連カテゴリの記事でさらに深掘りできます。相談やご依頼もお問い合わせページから受け付けています。

SQL練習場で試す お問い合わせ

この記事を書いた人:martechfarm

Treasure Data Top Lapidarist Award受賞。

SQL / Digdag / Python / CDP設計 / CRM設計を横断し、企業のデータ活用を支援。

実績・支援内容を見る →

MarTech Farmをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む