学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

HSQLDBを使用したデータベース入門その2 検索条件の指定

<<前  [TOP]  次>>


from句に複数のテーブルを指定するのは、select の形ではちょっと試しにくいです。


例えば、たった20行からなるテーブルどうしでも、積を作れば行数は20×20=400行になってしまいます。
もし1000行程度のテーブルなら、その積のテーブルは100万行にも膨れ上がってしまいます。
しかし、実務の世界では1000行規模のテーブルなどは、むしろ小さなテーブルと言えます。


これまでのselect文の使い方では、項目名の指定によってテーブルから不用な項目を切り落とし、必要な項目だけを残すことは出来ても、必要な行だけを残すことが出来ませんでした。


select文のwhere句は、この「検索される行が満たす条件の指定」という働きをします。


次の例では、「books2」テーブルから、300円以下の定価の図書の書名と、定価を表示させています。


【例1:定価300円未満の本を検索】

select title, price from books2 where price < 300; 




注意しておきたいことは、これらの比較演算子が数値に対しても文字列に対しても同じように使えるということです。
いくつかの例を挙げておきます。
文字列はシングル・クォート(')で囲まれていなければなりません。


where句の中で使える比較演算子には次のような種類があります。


=等しい
>大きい
<小さい
>=大きいか、あるいは等しい
<=小さいか、あるいは等しい
!=等しくない
<>等しくない


【例2:一致する出版社を検索】

select id, title, publisher from books where publisher = '社会出版';






論理演算子 and , or , not を用いて、条件部に、二つ以上の条件を組み合わせて指定することが出来ます。
先ほどの例では、単純に300円未満の本を検索しましたが、次のようにして、500円以上 1000円以下の本を探すことが出来ます。


【例3:500円以上、1000円以下の本を検索】

select title, price from books2 where 500 >= price and price <= 1000;




範囲の指定はよく使われるのですが、SQLでは次のような特別の構文「between 〜 and 〜」 が用意されています。
betweenでは、範囲指定の両端は含まれることに注意しましょう。


【例4:between 〜 and 〜】

select title, price from books2 where price between 500 and 1000;




論理演算子に「or」と「not」を使った例を見てみましょう。


次の例は「books」テーブルの中から、姓が'国語三郎'であるか、あるいは名前が'社会三郎'である人の書籍名を調べています。


【例5: or】

select title from books where author = '国語三郎' or author = '社会三郎';




notは、次の例のように用いられます。
ここでは、「books」テーブルから、publisherが「国語出版」でないtitleを選び出しています。


「not」と比較演算子「=」の組合せによる「where not publisher = '国語出版'」という部分は「!=」を用いて「where publisher != '国語出版'」というように書き換えることも出来ます。


【例6:国語出版以外のtitleを検索】

select title, publisher from books where not publisher = '国語出版';
select title, publisher from books where publisher != '国語出版';







国語三郎と社会三郎と理科三郎と英語三郎と算数三郎の本を出している出版社を捜し出したいとします。
この検索は、orを使えば、次のように書けます。


【例7:国語三郎と社会三郎と理科三郎と英語三郎と算数三郎の本を出している出版社を捜し出す】

select publisher, author from books where author = '国語三郎' or author = '社会三郎' or author = '理科三郎' or author = '英語三郎' or author = '算数三郎';




かなり命令文が長くなってしまいます。
こうした時SQLでは、次のようなかたちが用意されています。


【例8:国語三郎と社会三郎と理科三郎と英語三郎と算数三郎の本を出している出版社を捜し出すその2】

select publisher, author from books where author in ('国語三郎', '社会三郎', '理科三郎', '英語三郎', '算数三郎');




コンマ(,)で区切られカッコでくくられた部分を「リスト」と呼びます。


この形式はorの短縮形としてだけでなく、selectの内部で再びselectを呼び出す形式で頻繁に用いられます。


そのような形式での検索(subquery サブクエリーと呼ぶ)の例を示します。
次の検索は、「例8」と同じ結果をもたらします。


【例9:サブクエリー】

select publisher, author from books where author in (select keyword from keywords);




ちなみに、「keywords」テーブルの内容は次のようになっています。



真偽のいずれかの値を返す条件判断や、それらの間の論理演算は、多くのプログラム言語においても使われていますが、データベースでは論理演算と関連して特殊な値が定義されているのが大きな特徴です。
それがnull値です。
null値は、テーブル中に値として用いることができます。
値がnullだということは、その値がいまだ知られていないこと(未知)、あるいは、その値が未だに定まっていないこと(未定)、あるいは、どうなっているのか分からない(不明)ことを表していると解釈されます。


今、テーブル「books2」中のある本の定価がnullであったとします。
すなわち、ある本の定価がその時点で不明だったとします。


それでは、この本は次の二種類の検索のどちらで検索されるのでしょうか?

select title , price from books2 where price < 1000;
select title , price from books2 where price >= 1000;

一見するとすべての本は、どちらかの検索で見つかるように思えます。
しかし、定価がnull値をとっているということは、定価が分からないということであり、当然「この本の定価は千円未満である」という命令文と「この本の定価は千円以上である」という命令文のどちらが正しいか分からないということを意味しています。
なので定価がnull値の本は、上の二つの検索のいずれでも見つけだすことは出来ないことになります。


こうした解釈は、null値というのが単に値であるだけでなく、真あるいは偽とは区別された、「不明・未定・未知」といった状態を表す第三の真理値として解釈するのがよいでしょう。


null値の導入は、データベースの実際の運用上では非常に大きなメリットを持っていますが、なかなか面倒な問題も引き起こします。
次のような検索を考えてみましょう。

select title , price from books2 where price = null;



この検索は定価がnull値をとっている本を探しているのですが、残念ながらこの検索は成功しません。
確かに、null = null であるならば、この検索は成功するのですが、ここで比較されているのは定価の値です。
未知な定価と未知な定価とは、一般には等しくはありません。
そうした意味では、値としてのnull値は、自分自身とさえ一致しないのです。


それでは、null値をとる項目をどうしたら選び出すことが出来るのでしょうか?
SQLでは、その為に次のような構文が特別に用意されています。


【例10:定価が不明の本を検索】

select title, price from books2 where price is null;




次の例は、いうまでもなく「例10」の逆、すなわちnull値をとらない項目の検索です。
「is not null」を、「 != null」で置き換えることは出来ないことに注意しましょう。


【例11:定価が分かっている本を検索】

select title, price from books2 where price is not null;




SQLでは、いままで見てきたような与えられた文字列と完全に一致する文字列を含む行を検索するだけでなく、「国語」という言葉がつく出版社を調べたいとか、「算数」を書名に含む本があるかどうかを調べたいといった検索が可能です。


%任意の長さ(ゼロを含む)の文字列
_任意の1文字


この「ワイルドカード」を使うためには、where句の中で「like」を用います。


次の例では、「'国語'の後ろに何文字かが続く文字列」という意味になり、「国語」という言葉で始まる書名の本を検索することになります。


【例12:「国語」で始まる書名の本を検索】

select title from books where title like '国語%';




次の'%その5'という指定は、書名の最後に「三郎」が入っている本を探すことになります。


【例13:「その5」で終わる書名の本を検索】

select title from books where title like '%その5';




最初でも最後でも、ともかく書名中に「語」という言葉が入っている本を検索したいときには、'%語%'といった指定を用いればよいです。


【例14:「語」という言葉を含む本を検索】

select title from books where title like '%語%';




もしも、書名の途中に「1」という文字列を含む本を検索したいのなら、'%1%'の代わりに、「%_1_%」と指定すればよいです。
なぜなら、前後に「_」があることによって、少なくとも一文字は文字列「1」の前後にあることが、保障されるからです。


【例15:書名の途中に「1」という言葉を含む本を検索】

select title from books where title like '%_1_%';




ワイルド・カード「_」は、さらに次のような使い方が可能です。


【例16:8文字の書名の本を検索】

select title from books where title like '_____';




ここでのワイルドカード'_____'は'_'が8つ連続で記述されています。


この例では、8文字の書名の本が検索されます。
こうして、1文字の書名の本の検索( title like '_' )や、3文字の書名で最後が「語」である書名の検索( 書名 like '__語 ')等が可能になります。


<<前  [TOP]  次>>