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

checkboxでの値の管理

formにてcheckboxの値を一つのカラムにいれて管理する機会があったのですが、これ入力更新出会っても検索であっても処理がなかなか厄介です。特に検索の時ですね・・・ 要するに値の候補が1,2,3, …

no image

cakePHPでのマイグレーション

開発を続けているとデータベースのカラムの構造が変更するってことはしょっちゅうですが、管理がいい加減だとメンバー間でテーブルの構造が変わっていたり、本番と開発で違ってくるなどのトラブルが続出します。 そ …

no image

論理設計のアンチパターン

今回からは論理設計のアンチパターンについて。 やってはいけない設計のパターンですね。これはまわりがやっていると気づかずにやっている可能性があるのでしっかりメモしておきたいです。 Contents1 非 …

no image

エンティティの抽出と主キー決定

主に設計に関することのメモ。 Contents1 業務フロー分析2 エンティティの抽出3 エンティティの関連付け4 主キーの抽出を行う4.1 主キーの特徴4.2 サロゲートキーのメリット4.3 サロゲ …

no image

netbeansのJPQL補助機能

JPAでは基本的に生のSQLではなく、JPQLを使って書きます。 SQLでもタイプミスにイライラさせられることは多いのですが、JPQLはもっとですね・・・爆 そこで使えるのがNetbeansの入力補助 …