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

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

HSQLDBを使用したデータベース入門その2 検索条件の指定(2020年5月更新)

<<前  [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; 



「select title, price from books2 where price &lt; 300; 」
「select title, price from books2 where price < 300; 」


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


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


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


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

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


「select id, title, publisher from books where publisher = &#x27;社会出版&#x27;;」
「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;



「select title, price from books2 where 500 &gt;= price and price &lt;= 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;



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


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


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


【例5: or】

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



「select title from books where author = &#x27;国語三郎&#x27; or author = &#x27;社会三郎&#x27;;」
「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 != '国語出版';



「select title, publisher from books where not publisher = &#x27;国語出版&#x27;;」
「select title, publisher from books where not publisher = '国語出版';」
「select title, publisher from books where publisher != &#x27;国語出版&#x27;;」
「select title, publisher from books where publisher != '国語出版';」


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


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

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



「select publisher, author from books where author = &#x27;国語三郎&#x27; or author = &#x27;社会三郎&#x27; or author = &#x27;理科三郎&#x27; or author = &#x27;英語三郎&#x27; or author = &#x27;算数三郎&#x27;;」
「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 ('国語三郎', '社会三郎', '理科三郎', '英語三郎', '算数三郎');



「select publisher, author from books where author in (&#x27;国語三郎&#x27;, &#x27;社会三郎&#x27;, &#x27;理科三郎&#x27;, &#x27;英語三郎&#x27;, &#x27;算数三郎&#x27;);」
「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);



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


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

select * from keywords;



「select * from keywords;」
「select * from 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;



「select title, price from books2 where price is null;」
「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;



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


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


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


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


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


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

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



「select title from books where title like &#x27;国語%&#x27;;」
「select title from books where title like '国語%';」


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


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

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



「select title from books where title like &#x27;%その5&#x27;;」
「select title from books where title like '%その5';」


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


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

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



「select title from books where title like &#x27;%語%&#x27;;」
「select title from books where title like '%語%';」


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


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

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



「select title from books where title like &#x27;%_1_%&#x27;;」
「select title from books where title like '%_1_%';」


ワイルド・カード「_」は、さらに次のような使い方が可能です。
次の例ではワイルドカード'_'が8つ連続で記述されています。
そうすることで8文字の書名の本を検索することができます。


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

select title from books where title like '________';



「select title from books where title like &#x27;________&#x27;;」
「select title from books where title like '________';」


このワイルド・カード「_」を使うことにより、1文字の書名の本の検索( title like '_' )や、3文字の書名で最後が「語」である書名の検索( 書名 like '__語 ')等が可能になります。


<<前  [TOP]  次>>