SQLという言語は「とりだしてくっつけ、あつめてちゅうしゅつし、さいごにいらないのを捨てる」仕組みに過ぎない。

徒然草2.0

結論から言えばSQLができることはテーブルからデータを「とりだしてくっつけ、あつめてちゅうしゅつし、さいごにいらないのを捨てる」だけの仕組みに過ぎません。何のことを言っているのか伝わらないと思いますが…まずはロジカルに考えるより先に集計といはそういうものだとざっくり理解することが大切なのではないか?という問題提起をしたい…というメモです。はい。SQL記述者全員が理解すべきSELECT文の実行順序のお話 という記事を読みました。私はSQLは感覚的に使っているので実行順序とかを意識していません。いや意識していないと言ったらおかしいですが、特に何も考えないで「こんなものだ」と思って使っています…というよりSQLというかRDBMSも所詮はループと条件によって処理されるプログラムの一種に過ぎないと分かった時、コストの計算ができるようになるって感じです。

(別にこの記事がいけないわけではありません。ただ、私が感覚的に理解していることをきちんと文章にするとこうなるのだな汗、という発見をさせていただきました汗)ということを踏まえて思うに…つまるところ、from->join->where->group by->having->select->order by->limitなんて呪文のように覚える必要はないということを言いたい。

…おそらくこの外部リンク記事の筆者もフローで理解したうえで腑に落とす感覚を持っているような書き方をしているように思います。

なんとなくSQLを書き下していくうちに上記の流れが体得できるって感じに近い?と言っても説明しても伝わらないと思いますし、SQLを習得することはできないですが、一応それはどういうことかを書き表してみたいと思います。さて、


SQLとは…

(どれ?)データストアからデータを取り出すその対象をfrom句でまず指定します。まず「どれ?」が分からないと情報処理の対象がわからないので当然ですね。次に…

(どれ?とどれ?をくっつける?)という情報を記述するのにjoinを持ちいるわけですが、結果としてwhereでもinner joinができるという意味ではjoinもwhereも同じ仲間ですね。

(どれを集計して?条件づける?)という情報を記述するのにgroup by がありgroup byがでてきた時にのみhavingを用います(group by はhavingの枕詞である…という説明では例外があるかもしれないですが…)

(不要なものを捨てる)最後にlimitで不要なレコードを削って出力します。whereやhavingなどで削れたらいいですが全て取得して集計しないと捨てていいかどうか判断できないので…ここで削るというわけ。

このプロセスを実行する言語である。


まとめると…

どのテーブルにどのテーブルを連結させるたいの?…ということをfrom,whereで定義した後、集計したり抽出したりをgroup by,havingで行い、limitで最後に不要分は捨てる。

これをもっと簡略化すると…

とりだしてくっつけて、あつめてちゅうしゅつ(さいごにいらないのを捨てる)。

1.とりだしくっつけ

2.あつめてちゅうしゅつ

3.さいごにいらないのすてる

ぷよぷよで連鎖させるために積み上げる時も同じロジックです(?)

RDBの情報処理とは、この基本ロジックを守れば大抵のデータを取り出せるという、かなりシンプルなルールに従っているものだということになります。

その過程で、「なんでWHERE句でSUM関数(集約関数)は使えないの?」については、とりだしたデータをくっつけていない関係性が成立していない状態で集計なんてできるわけがないのは明白ですし「なんでSELECT句のASはORDER BY句では使えるのに、WHERE句では使えないの?」についてはまだくっつけていない関係性が成立していない状態でカラムへの名づけができるわけがないのは明白ですし「なんでLIMITで出力行数を絞っているのに、処理時間は変わらないの?」については集計した結果を切り捨てる結果だから過程の処理時間を端折れないことは明白です…とはいえ、コメント欄にあるようにRDB製品によってはlimitが最適化されて処理時間が短縮する場合もあるそうですが、それはRDBMSの応用アルゴリズムであって学習においてはまず上記のデータ扱いの本質をつかむべきなのでは?と思います。

コメント

タイトルとURLをコピーしました