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

集合としてのSQL

今まで何度かSQLが集合ということを扱ってきました。 今回はそれがよくわかる例を。 実務ではあまりないと思うのですが、集合をイメージしやすい例題として、2つのテーブルが全く同じケースを考えます。 下記 …

no image

NOT EXISTSの利用2

今回もNOT EXISTSの利用です。 前回の問題にプラスアルファし、列が一緒でないと連続でも意味ない仕様にします。 例えば下記のようなテーブルがあるとします。 seat | row_id | sta …

no image

SQLにおけるナンバリング

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

no image

HAVING句について

本日はHAVINGについて。 かろうじて用法はしっており、たまに使うこともありますが、あまりしっかり理解しているとはいえない状況ですので、掘り下げてみようと思います。 WHEREとは違い、抽出した結果 …

no image

DBの構造について メモリとHDD

データベースについてまたまた学習中。 覚えておきたいポイントなど。 データを収めておくべき媒体では「記憶コスト(単位金額当たりの容量)」と「アクセス速度」の2つが重要なパラメータ メモリとHDDでは前 …