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

NULLについて

「達人に学ぶSQL徹底指南書」を読み進めていきましたがNULLについていろいろ書いてあるのでメモリます。 Contents1 NULLには未知と適用不能の2パターンがある2 = NULL が使えず I …

no image

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

今回は論理設計のアンチパターンの続きです。 今までに比べると何も意図がないというものではなく、パフォーマンスを考えて設計されているようなものが多いです。 ただし、中には絶対に許されないタイプのものもあ …

no image

オプティマイザと実行計画

データベースがSQLを受け取って処理を実行する前には下記のような段階があります。 Contents1 パーサー2 オプティマイザ3 カタログマネージャー4 参考リンク パーサー SQL構文のチェックし …

no image

SQLクエリ比較

クエリの比較 SQLにおいては全く同じ結果を返すのであってもその検索結果が異なるということはよくあります。 例えば下記のようなテーブルがあった場合 co_cd | district —&# …

no image

Postgresの基礎(主にMySQLとの違いなど)

えー来月(2020年3月)より、postgresを使うかもしれないので、ちょっと復習を。 Contents1 以前のリンク2 基本コマンド比較2.1 超頻出系3 テーブル比較4 SELECT文5 do …

アーカイブ