skillup

技術ブログ

Database

SQL case式やウィンドウ関数の威力

投稿日:

プログラマには「プログラムは思った通りに動かない。書いた通りに動く。」「バグではない仕様です」なんて面白い格言がいろいろありますが、データベースの世界にも「WHERE句で条件分岐させるのは素人のやること。プロはSELECT句で分岐させる」という格言があるそうです。

初めて聞いたのですが、ひとえに私の経験が浅いからでしょう(爆)

SQL実践入門を読んでいて面白かったSQL問題などをちょこちょこと書いていこうと思います。(データなどはちょっといじっていますが)

テーブル名 postalcode

pcode district_name
4130001 サンプル県サンプル市1
4130002 サンプル県サンプル市2
4130103 サンプル県サンプル市3
4103213 サンプル県サンプル市4
4380824 サンプル県サンプル市5

上記のようなリストがあった時、検索語句(4130033)の合致度が高いもの3つを選べ。

合致度とは4130033と合致している桁数が多いものですね。

例えばこの場合、4130001と4130002は41300まで合致していますので、合致度が高くなります。

この選び方ですが、whereを使わずにcase式でサクッと行けます。

もう一問。今度はウィンドウ関数を使うと比較的楽に解ける問題です。

テーブル名 receipts

cust_id seq price
A 1 500
A 2 1000
A 3 700
B 5 100
B 6 50000
B 7 300
B 9 200
B 12 1000
C 10 600
C 20 100
C 45 200
C 70 50
D 3 2000

上記のテーブルでcust_idのseqが最大値のものと最小値の差を求めよ。
※例 Aの場合はseq=1が最小値でseq=3が最大値なので差は200となります。

この場合まず、cust_idごとの最大値と最小値を求めなければなりませんが、サブクエリを作るなどやると式が複雑になります。PostgreSQLなどであればPARTTIONを使い、

これで上のテーブルにランクをのせたテーブルにすることが出来ました。

この後はmax_seq_rank =1 のpriceとmin_seq_rank=1の引き算を行います。

これまたcaseを使うと下記のように比較的楽になります。

コツとしては一気にやらずに部分から組み立てていったほうがよいでしょう。また引き算の部分はまずおのおのの数値を出した後計算したほうがよいです。

私もいきなりやろうとすると挫折しましたので・・・・

-Database
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

サブクエリ 分析関数の代替案として

今回は分析関数系のネタです。 以前にも分析関数を少し学習しましたがMySQLにはないので、サブクエリを使い書くことになります。 下記のような入出金講座があるとします。 Accounts prc_dat …

no image

SQLにおけるナンバリング

本日はナンバリングに関して。 MySQLを使っていますと各テーブルにはid int not null auto_increment primary keyなどと打って主キーを打つことがほぼ習慣になって …

no image

SQL問題

今までやったSQL問題などのまとめ。定期的にやる予定です・・ 自分用なのでテーブルデータとかあったりなかったりいい加減です(汗) SQLドリル 問題1 nameとageで構成されたテーブルがあるとして …

no image

JPAでのリレーションに関して

JPAではテーブルをクラスで定義します。もちろん例外とかはいろいろあるのですが、1テーブル1クラスというつくりで、これをエンティティと呼びます。 もともとクラスを作ってからDBを作成したり、JTAの規 …

no image

サブクエリの使い方

以前も少し学習しましたが、今回からはサブクエリの扱い方です。特に異なった行の比較(年度計算など)に関して行われる自己結合をつかったものが非常に強力です。 例によってここを学習しています。 下記のような …

アーカイブ