テーブル行を「selectで行を列」に入替えたい時は、時折必要となります。
簡単な例で、そのサンプルを纏めておきます。
『Window関数』で『select&集計』を楽にする
MySQL8からWindow関数が使えるようになったので、その基本的な使い方と利用用途を整理してみました。
只、全て整理しても書くの大変で内容もボヤケてしまうので、これは使えるかも?という観点で少しずつ範囲を広げてみようと思います。
Window関数とは?
PostgresqやOracleでは前から備わっていたようですが、ザクっと「selectするときに集計結果も取得できる」 ものと一先ず理解しています。
逆に言えば、selectと集計を分けて連結すれば求めることはできますが、何といっても記述が圧倒的に短く「楽ちん」できるところがメリットだと思います。
『一括JOIN』と『SELECT分割』の組み立ての考察
SQLZOOというSQLの結果も返してくれる、とても優れたSQLの学習サイトがあるのですが、以前、社内の若手を中心にこのサイトの問題を勧め解いて貰いました。
初歩的なものも多いのですが、SQL入門者でも熟練者の復習としても、とてもよい教材でお勧めです。
最後のSelf join は、単純テーブル構成ながら、幾人かは ここの最終問題辺りで詰まってクリアに至らなかったのですが「Self join」を理解する上でとても秀逸なTutorialだと思います。
ここでは、このSelf join の「#8」に焦点を当てて「join」の組み立ての違いについて考察してみたいと思います。
Self join のテーブルを参考にさせて頂き、より日本人(特に大阪人)に馴染みやすい以下の表を用意しました。
『NOT IN』『NOT EXISTS』の検証
『INDEX』のキホンで、否定条件(NOT IN等)はINDEXが効かず性能的に使用は避けるべきと書きました。
確かに「NOT IN」より「NOT EXISTS」を使うべきだとされていることもありますが、しかし昨今のRDBでは、何かと最適化もされているので実のところどうなのでしょうか・・・
この他にも「LEFT JOIN + IS NULL」も代用できますが、これらの違いを各RDBでの性能の違いを検証してみました。
『JOIN』と『SELECT列のサブクエリー』の性能検証
「JOIN」と「SELECT列のサブクエリー」は、他のテーブル情報をキーを使って取得するという点においての効用としては似ています。
私の場合は、JOINで取れるものは、サブクエリーは基本使いませんが、その理由は「可読性」もありますが「性能的」にもサブクエリーは劣っているという印象もあります。
しかし、昨今のオプティマイザや処理の最適化が行われている、RDBではどのような結果になるのか気になったので、単純なサンプルを使って代表的なデータベースそれぞれの性能的な違いを検証してみました。
(PC環境やデータベースのバージョンやドライバやデータ件数、使用ツールの違いで結果が異なる場合があるので、あくまで参考として頂ければと思います。)