SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ビジネスデータ解析のためのSQL入門

SQLで基本のデータ解析に挑戦する

ビジネスデータ解析のためのSQL入門 第1回


クロス集計

 クロス集計とは、特定の情報(通常は2種類)を縦軸と横軸に割り振り、相関や変化を表にして表現する集計方法です。アンケート調査の分析などでよく使われます。

クロス集計の例
クロス集計の例

SQLサンプルと解説

 サンプルとして冒頭で準備した顧客テーブルを用います。

 縦の集計値として「sex(性別)」、横の集計値として「place(地域)」を用いて、ユーザー数を集計したいケースを考えます。

 欲しい結果は以下です。

   sex    | tokyo | osaka | fukuoka
----------+-------+-------+---------
 M        |     2 |     2 |       1
 W        |     4 |     1 |       2

 SQLはリスト5のようになります。単純な集計のように思えますが、サブクエリが必要なため少々複雑です。順を追って確認していきます。

リスト5 クロス集計のSQL(cross-tab.sql)
select/* (3) */
    sex,
    max(case seq_tmp when 1 then uu_count else null end) as tokyo,/* (3)-(a) */
    max(case seq_tmp when 2 then uu_count else null end) as osaka,
    max(case seq_tmp when 3 then uu_count else null end) as fukuoka
from(
    select
        *,
        row_number() over (partition by sex) as seq_tmp/* (2) */
    from(/* (1) */
        select
            sex,
            place,
            count(user_id)as uu_count/* (1)-(b) */
        from
            customer
        group by place,sex/* (1)-(a) */
        order by place desc
        )count_tmp
    ) x
group by
    sex
;

(1)性別・地域ごとのユーザー数集計

 内側のクエリから確認していきます。

  • (a)sex、place列で集計します。
  • (b)ユーザー数をcount関数で集計し、uu_countとします。

 このクエリによって得られる途中結果は以下です。

   sex    |      place       | uu_count
----------+------------------+----------
 M        | Tokyo            |        2
 W        | Tokyo            |        4
 M        | Osaka            |        2
 W        | Osaka            |        1
 W        | Fukuoka          |        2
 M        | Fukuoka          |        1

(2) 「地域」に連番を付与する

 上のテーブルをもとに、「横の分類」で表現したい項目で連番を取ります。「Tokyo=1,Osaka=2,Fukuoka=3」となるように連番を付けます。

 連番を付与するのはrow_number関数の役割です。性別ごとにそれぞれ連番を取るため、sexでグルーピングしています。

 row_number関数の構文は以下の通りです。項目1でグループ化し(オプション)、項目2でソート後に番号を付与します。

row_number関数の構文
ROW_NUMBER ( ) OVER ( [ PARTITION BY <項目1>  ] ORDER BY <項目2> )

 この時点で結果は以下のようになります。

   sex    |      place       | uu_count | seq_tmp
----------+------------------+----------+---------
 M        | Tokyo            |        2 |       1
 M        | Osaka            |        2 |       2
 M        | Fukuoka          |        1 |       3
 W        | Tokyo            |        4 |       1
 W        | Osaka            |        1 |       2
 W        | Fukuoka          |        2 |       3

(3)CASE式で集計値を縦方向から横方向に変換する

 CASE式を使ってseq_tmpで指定される番号ごとにユーザー数の集計値を表示させます。

 CASE式の構文は以下の通りです。構文は2種類あり、WHENのあとに値のみ記述する構文(単純CASE式)と、「<項目> = <値1> 」のように式を記述する構文(検索CASE式)があります。

 上のリスト5では単純CASE式の構文を利用しています。

単純CASE式の構文
 CASE  <項目>
   WHEN <値1> THEN  <値4>
   WHEN <値2> THEN  <値5>
   ELSE <値3>
 END
検索CASE式の構文
 CASE WHEN <項目> = <値1>  THEN  <値4>
      WHEN <項目> = <値2>  THEN  <値5>
 ELSE  <値3>  END

 例えば(a)の行では、seq_tmpが1である(=Tokyoのユーザー数の集計値)のみが実際の数値で、あとはNullとなるため、max関数で対象となるユーザー数の集計値だけが表示されます。以上で、「性別ごと」「地域ごと」の2軸で集計ができました。

次のページ
デシル分析

この記事は参考になりましたか?

ビジネスデータ解析のためのSQL入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 西 潤史郎(ニシ ジュンシロウ)

WINGSプロジェクト について>有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 山田...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10154 2017/08/02 12:17

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー