0Pricing
Coding Interview Prep · レッスン

累積分布と全体に占める割合

パーティション内で累積割合と全体に占める比率を計算します。

「累積分布と全体に占める割合」はCoddyKit上の無料Coding Interview Prepレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCoding Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Coding Interview Prepコースには全4レッスンが含まれています。

全体に占める割合の質問

レポート作成の面接で定番の質問です。「各カテゴリは総売上の何パーセントを占めますか。」また、その累積版として「全体に占める累積割合はどれくらいですか。」という質問もあります。

ポイントは、各行の値をパーティション全体に対して計算したウィンドウ集計で割ることです。自己結合を使わず、ウィンドウ関数に総合計を含められることが、ここで試されている理解です。

ORDER BYなしのウィンドウSUM = 総合計

ここが重要なポイントです。空の OVER、つまり ORDER BYを指定しない SUM(amount) OVER () は、結果セット全体の合計をすべての行に繰り返して返します。

ORDER BY がないため累積フレームは存在せず、デフォルトのフレームはパーティション全体になります。すべての行に表示されるこの合計値が、全体に占める割合を計算するために必要な分母です。

SELECT
  category,
  amount,
  SUM(amount) OVER () AS grand_total
FROM category_sales;

全体に占める割合を計算する

行の値をウィンドウ関数で求めた総合計で割り、100を掛けます。整数除算によって小数部分が切り捨てられないように、10進数にキャストしてください。

この1回のクエリで、合計を求めるサブクエリを明細行に結合する従来のパターンを置き換えられます。より短く、高速で、読みやすいクエリになります。

SELECT
  category,
  amount,
  ROUND(
    100.0 * amount / SUM(amount) OVER (),
    2
  ) AS pct_of_total
FROM category_sales;

整数除算の落とし穴

面接でよく出る定番の落とし穴です。多くのデータベースでは、整数列に対する amount / total は整数除算になります。そのため、1未満の結果は0になります。

これを防ぐには、最初に 100.0(数値リテラル)を掛けるか、一方のオペランドをキャストします。amount::numeric / total のように記述します。これを忘れると、0だけの列が返されるため、面接官にもすぐ見抜かれます。

SELECT
  category,
  amount * 1.0 / SUM(amount) OVER () AS share,
  CAST(amount AS DECIMAL) / SUM(amount) OVER () AS share_alt
FROM category_sales;

グループ内での全体に占める割合

PARTITION BY を追加すると、各行の割合をテーブル全体ではなく、そのグループを基準にできます。たとえば、各商品の所属地域の売上に占める割合を求められます。

分母の SUM(amount) OVER (PARTITION BY region) は地域ごとにリセットされるため、各地域内の割合の合計は100になります。

SELECT
  region,
  product,
  amount,
  ROUND(
    100.0 * amount / SUM(amount) OVER (PARTITION BY region),
    2
  ) AS pct_of_region
FROM regional_sales;

全体に占める累積割合

累積する分子と固定された分母を組み合わせると、全体に占める累積割合を求められます。これは、各行までに総合計のどれだけが蓄積されたかを表します。

分子では ORDER BY を使って累積し、分母では空の OVER () を使って総合計を求めます。最後の行は必ず100%になります。

SELECT
  sale_date,
  amount,
  ROUND(
    100.0 * SUM(amount) OVER (ORDER BY sale_date)
          / SUM(amount) OVER (),
    2
  ) AS running_pct
FROM daily_sales;

CUME_DIST:累積分布

SQLには累積分布を求める組み込み関数として CUME_DIST() があります。これは、現在の行以下の ORDER BY 値を持つ行の割合を返します。値は (0, 1] の範囲になります。

金額の累積割合を手動で計算する方法とは異なり、CUME_DIST は行の位置を扱います。つまり、「この値以下の行は全体の何割か」という問いに答える関数です。パーセンタイル形式のレポートに役立ちます。

SELECT
  score,
  CUME_DIST() OVER (ORDER BY score) AS cume_dist
FROM exam_results;

PERCENT_RANKとその違い

近い関数に PERCENT_RANK() があります。これは (rank - 1) / (total_rows - 1) と定義され、0から1の範囲になります。

面接で説明すべき違いは、CUME_DIST が現在の行を分子に含む(「この値以下」)のに対し、PERCENT_RANK は最初の行を0として始まる相対順位だという点です。両者は異なる値を返すため、混同するのはよくあるミスです。

SELECT
  score,
  CUME_DIST()    OVER (ORDER BY score) AS cd,
  PERCENT_RANK() OVER (ORDER BY score) AS pr
FROM exam_results;

パレート/80-20分析

全体に占める累積割合は、パレート分析に活用できます。たとえば、「上位の顧客のうち、どの顧客までで売上の80%を占めるか」という問いです。金額の降順で並べ、累積割合を計算してから、累積割合が初めて80%を超える位置までを抽出します。

ウィンドウ関数の結果は WHERE では使えないため、計算をCTEで包み、外側のクエリで絞り込みます。これは、すべてのウィンドウ関数に共通するルールです。

WITH ranked AS (
  SELECT
    customer_id,
    revenue,
    SUM(revenue) OVER (ORDER BY revenue DESC)
      / SUM(revenue) OVER () AS running_share
  FROM customer_revenue
)
SELECT *
FROM ranked
WHERE running_share <= 0.80;

丸めと整合性調整

注意してください。各パーセンテージを小数点以下2桁に丸めると、列の合計がちょうど100ではなく99.99や100.01になることがあります。面接官は、各部分の合計が全体と一致することをどのように保証するかを尋ねることがあります。

よくある回答は、表示時だけ丸める、計算では完全な精度を維持する、または最大剰余法による調整を1行に適用する、といったものです。修正方法よりも、問題を指摘できることのほうが重要です。

面接で伝える要点

口頭で説明できるようにしておく重要なポイント:

  • SUM(x) OVER ()でORDER BYを指定しない場合、すべての行に総合計が表示されます。
  • 整数除算を避けるには、100.0を掛けます。
  • グループごとの割合にはPARTITION BYを使います。
  • 総合計を分母とし、累積値を分子にすると、累積割合になります。
  • 分布にはCUME_DISTとPERCENT_RANKを使います。それぞれの違いを理解しておきましょう。
  • Pareto分析やしきい値によるフィルタリングでは、CTEでラップします。

確認問題

結果セット全体の総合計を、すべての行に表示するにはどうすればよいですか?

まとめ:分布と全体に対する割合

全体に対する割合は、各行の値をSUM(x) OVER ()で割って求めます。SUM(x) OVER ()はすべての行に総合計を返します。整数除算を避けるため、必ず100.0を掛け、グループごとの割合にはPARTITION BYを追加します。総合計を分母とし、累積値を分子にすると、最終的に100%になる累積割合が得られます。これはPareto分析の基礎となります。

順位に基づく分布にはCUME_DISTとPERCENT_RANKを使い、丸めと整合性調整に関する注意点も覚えておきましょう。これで累積合計と移動平均の学習は完了です。

よくある質問

「累積分布と全体に占める割合」レッスンは無料ですか?

はい。「累積分布と全体に占める割合」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Coding Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Coding Interview Prepコースには全4レッスンが含まれています。

「累積分布と全体に占める割合」で何を学びますか?

パーティション内で累積割合と全体に占める比率を計算します。 ブラウザで直接実行するハンズオンコードでCoding Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Coding Interview Prepを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのCoding Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「累積分布と全体に占める割合」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このCoding Interview Prepレッスンでコードを書いて実行できますか?

はい。すべてのCoding Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ウィンドウフレームで累積合計を求める
  2. ROWSとRANGEのフレーム指定
  3. スライディングウィンドウで移動平均を求める
  4. 累積分布と全体に占める割合
← Coding Interview Prepに戻る