超電磁砲でデータベース(入門編)

はじめに

前回でデータベースの入力は済んでいるものとする。sqlite3.exe を起動し、次のコマンドを打ち込む。.mode column の代わりに .mode html を入力すると html 形式で結果が得られ、教材の編集には便利である。

.open railgun.db
.mode column
.headers on

NULL

NULL はヌルではなく、ナルと読む。何もないことを表す用語である。

前回と同じテーブル STATUS を利用する。レベル5の人物を検索して名前と能力名を表示しよう。

SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 ;

NAMESKILL
御坂美琴レールガン
一方通行アクセラレータ
麦野沈利メルトダウナー
食蜂操祈メンタルアウト
垣根帝督ダークマター
藍花悦
削板軍覇

7行の結果が表示されたが、下2行の LEVEL 欄は空白である。これは値が登録されていない状態であり、NULL と表現される。下2行を区別するためには、LEVEL が NULL であることを記述する必要である。NULL は値として扱われないことになっていて、LEVEL=NULL とはできず、LEVEL IS NULL と表現することになっている。また、NULL でない場合は IS NOT NULL を使う。

課題
(1) レベル5かつ能力名が登録されていない人物を検索し、 名前を表示せよ。
(2) レベル5かつ能力名が登録されている人物を検索し、 名前 と 能力名 を表示せよ。

解答例 (前回は分かりやすさのため括弧を多用したが、今回は省略した)
(1) SELECT NAME FROM STATUS WHERE LEVEL = 5 AND SKILL IS NULL ;

(2) SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 AND SKILL IS NOT NULL ;
(別解)SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 AND NOT (SKILL IS NULL) ;

ORDER BY

問い合わせ結果の表示順序を整えたいという要望は当然ある。それを実現するのが ORDER BY である。例えば、問い合わせ文の最後に ORDER BY LEVEL のように付け足せば、表示結果を LEVEL の昇順に並べ替えてくれる。降順にしたければ ORDER BY LEVEL DESC と DESC を付け加える。複数の項目を並べて辞書式順序で指定することもできる。

課題
SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 AND SKILL IS NOT NULL ; の出力結果を指示に従って並べ替えよ。
(1) 能力名の昇順
(2) 能力名の降順

解答例
(1) SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 AND SKILL IS NOT NULL ORDER BY SKILL ;

(2) SELECT NAME, SKILL FROM STATUS WHERE LEVEL = 5 AND SKILL IS NOT NULL ORDER BY SKILL DESC ;

課題
SELECT LEVEL, SKILL FROM STATUS WHERE (LEVEL = 4 OR LEVEL = 5) AND SKILL IS NOT NULL ; でレベル4と5のレベルと能力名の組が出力される。出力結果を指示に従って並べ替えよ。自書式順序はレベル、能力名の順とする。
(1) レベル、能力名ともに昇順
(2) レベルは降順、能力名は昇順

解答例
(1) SELECT LEVEL, SKILL FROM STATUS WHERE (LEVEL = 4 OR LEVEL = 5) AND SKILL IS NOT NULL ORDER BY LEVEL, SKILL ;

(2) SELECT LEVEL, SKILL FROM STATUS WHERE (LEVEL = 4 OR LEVEL = 5) AND SKILL IS NOT NULL ORDER BY LEVEL DESC, SKILL ;

DISTINCT

レベル4の能力名を表示してみよう。

SELECT LEVEL, SKILL FROM STATUS WHERE LEVEL = 4 AND SKILL IS NOT NULL ORDER BY SKILL ;

“4 テレキネシス” と表示される行が2つ見つかるだろう。重複表示を削除するために DISTINCT が使用できる。次のように DISTINCT を追加すれば、重複行がなくなる。

SELECT DISTINCT LEVEL, SKILL FROM STATUS WHERE LEVEL = 4 AND SKILL IS NOT NULL ORDER BY SKILL ;

LIKE

前回、文字列の比較を行ったが、一致するかどうかしか判定できなかった。部分マッチングを可能にするのが LIKE である。具体例で説明しよう。名前が「上条当麻」のデータを探したい場合、これまでなら NAME = ‘上条当麻’ とする必要があり、仮に「上条」で始まることしか分からなかったら検索できなかった。LIKE を使えば、不明の部分を % で表し、NAME LIKE ‘上条%’ として検索することが出来る。

SELECT * FROM STATUS WHERE NAME LIKE ‘上条%’ ;

課題
(1) 「上」を含む名前を検索せよ。
(2) 「ハンド」で終わる能力名を検索せよ。
(3) 「土御門」で始まる名前を検索せよ。

解答例
(1) SELECT NAME FROM STATUS WHERE NAME LIKE ‘%上%’ ;

(2) SELECT SKILL FROM STATUS WHERE SKILL LIKE ‘%ハンド’ ;

(3) SELECT NAME FROM STATUS WHERE NAME LIKE ‘土御門%’ ;

BETWEEN, IN

範囲指定に使える文法として BETWEEN と IN を追加する。\( 2 \leq \) LEVEL \( \leq 4 \) を表すとき、2 <= LEVEL AND LEVEL <= 4 などとしてきた。これを BETWEEN を使って LEVEL BETWEEN 2 AND 4 と表すことが出来る。また、IN を使うと LEVEL IN ( 2, 3, 4 ) と表すことが出来る。

課題
次の問い合わせを指示に従って書き換えよ。
SELECT NAME, LEVEL FROM STATUS WHERE 1 <= LEVEL AND LEVEL <= 3 ORDER BY LEVEL ;
(1) BETWEEN を使って書き換えよ。
(2) IN を使って書き換えよ。

解答例
(1) SELECT NAME, LEVEL FROM STATUS WHERE LEVEL BETWEEN 1 AND 3 ORDER BY LEVEL ;

(2) SELECT NAME, LEVEL FROM STATUS WHERE LEVEL IN ( 1, 2, 3 ) ORDER BY LEVEL ;

IN は ( ) 内に列挙するので、かなり汎用的に使える。

課題
能力名が「エアロハンド」「テレキネシス」である人物を検索し、名前と能力名を表示する問い合わせを IN を使って書け。

解答例
SELECT NAME, SKILL FROM STATUS WHERE SKILL IN ( ‘エアロハンド’, ‘テレキネシス’ ) ;

表示に関する補足

これまでの問い合わせ文で項目の表示は NAME, LEVEL, SKILL と属性そのままであったが、AS を使って表示を変更できる。例えば、次のようにすれば NAME, LEVEL, SKILL と表示されていたものが、名前、レベル、能力名と変更される。

SELECT NAME AS ‘名前’, LEVEL AS ‘レベル’, SKILL AS ‘能力名’ FROM STATUS WHERE LEVEL = 5 AND SKILL IS NOT NULL ;