SQLer 生島勘富 のブログ

RDB・SQLの話題を中心に情報発信をしています。

OLAP(分析)関数について -- SQLはテストファースト指向

 OLAP(分析)関数は考え方としては、SQLの他の構文よりも手続き型言語と差が小さい。

 考え方ではなく、文法から入る人にとってはとんでもない違いに感じるかも知れませんが、答えは同じなのですから違いはないのです。

 長くなるので数回に分けて書こうと思う。

ざっくりとした考え方(毎回)

 GROUP BY は集約するので、結果が(集約キーを出力すれば)一意になる。つまり、出力される結果が一意になるまで集約される。

 しかし、OLAP(分析)関数は、SELECTされた結果を区切って処理する。そのため、レコード数に変化はない。

    集約する → GROUP BY
    区切る → PARTITION BY

 となる。これだけが分かっていれば実は簡単です。

イメージしてみましょう。

 いつも例題に使っているのは少しややこしいので、以下の条件で考えてみましょう。

 ■要望

 ■納品書明細(テーブル)
   納品書番号
   行
   商品ID
   単価
   数量
   消費税率

 というテーブル構造にで、消費税率は一律5%が入っています。
 消費税は、納品書単位に金額を合計したものに消費税率を掛け、四捨五入して請求しています。
 しかし、経理上、明細毎の消費税額が必要になり、明細単位に四捨五入すると、請求した消費税との誤差が発生します。
 その誤差を明細合計金額の多い順に1円ずつ増減して消費税額を計算してください。

 この要望を聞いて、私が持つイメージはこんな感じ。


拡大する

 一方、手続き型で考える人はこんな感じじゃないかな?(あくまで私の想像です)


拡大する

 それとも、オブジェクト指向で考える人はこんな感じか……?(あくまで私の想像です)

 それはともかく、処理の部分を文字に起こすと……。

     明細毎に消費税計算して四捨五入して合計する。 …… A
     納品書単位の合計金額に消費税率を掛け四捨五入する。 …… B
     納品書毎の誤差金額を計算する(B − A)。
     誤差金額の絶対値より明細金額の多い順位(1オリジン)が同じか小さいとき
         誤差金額が正なら1円、負なら-1円を Aに加算する。

 要望を手続き(アルゴリズム)に直す、つまり、文字に起こすのが設計で、設計を元にプログラムにするのが実装。というのが常識の世界では、こういう手続きのイメージがすらっと出てくるのは確かに能力が高いと言える。実際にこの程度でも1時間以上掛かる人も多い。というか、できない人もいるから問題が起きたりする(苦笑)。

 しかし、手続き型でやる人も、多くはテストをするときに


拡大する

 の様なものを作るんじゃないかな?答えがなかったらテストできないでしょう。
 つまり、SQLの考え方を身に付けるには、
    手続き(アルゴリズム)→ 実装 → テスト
 という考え方の順番を
    テスト(準備) → 実装 → テスト
 と逆にすることができれば良いのです。


 手続き型言語は「どうする(HOW)」から考えるが、宣言型言語は「何が欲しい(WHAT)」から考えるのが特徴です。もちろん、宣言型言語にカテゴライズされるSQLも、まず「何が欲しいのか」から考えないとできない。テスト(用プログラム)を書くわけではないけれど、「何が欲しい(WHAT)」から入るSQLテストファースト指向とも言えるでしょう。

 SQLを身に付けるのに、手続き(アルゴリズム)から考えるクセがついている人は、最初のうちはSQLを考えずに、エクセルを使って単純な関数で答えが出せるところまで作ればよいです。エクセルで答えが出せたら、ほぼSQLでできます。

 イメージでできるようになるには、頭の中で計算途中に必要な導出項目を含めすべてを羅列します。そして、それぞれの導出項目についてSQLで表現できるかを頭の中でチェックして、できると判断したら頭の中ではSQLは完成となります。慣れてくれば、チェックしなければいけない導出項目はどんどん減ってきますから会話のペースで出来るようになります。

 簡単でしょう(笑)。やってることは同じなので、チェックする時点で手続き型言語にも会話のペースで翻訳できるんですけどね。

 余談ですが、現場では SE に説明するために、上の様なエクセルイメージを予め用意して来るユーザもいらっしゃいます。もちろん、項目が漏れていたり、間違いがあったりもするけれど、完璧なモノを提示されると「スカウトしたいな〜」「その辺のSEよりずっと良いセンスしてるな〜」って思ってしまう。

 もともと「手続き(アルゴリズム)を考えなくてもできる」という目的でSQLはできたので、当たり前の話ですね。手続き(アルゴリズム)ではなく、何が欲しいかから考えるという点で、ユーザ側や所謂上流技術者に向いている言語です。

 全く、OLAPの話までいけなかったが、続きは次回