はじめに
前回でデータベースの入力は済んでいるものとする。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 ;
NAME | SKILL |
---|---|
御坂美琴 | レールガン |
一方通行 | アクセラレータ |
麦野沈利 | メルトダウナー |
食蜂操祈 | メンタルアウト |
垣根帝督 | ダークマター |
藍花悦 | |
削板軍覇 |
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 ;