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

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

HSQLDBを使用したデータベース入門その4 selectのネスティング

<<前  [TOP]  次>>


テーブルのジョインを行うには、もう一つの方法があります。
それはselect文の内部で再びselect文を用いる方法です。


ここでのselectのネスティングでは、次の
where 項目名 in ( select 項目名 from ..... )
という形が特徴的です。
ここでの二つの項目は、もちろん、同じタイプに属さなければなりません。
加えて、内側のselect文は、一つの項目のみを返すものでなければならないことに注意してください。


逆に、こうした要件が満たされていれば、in 以外の比較演算子を置くことも可能です。
例えば・・・
where 項目名 = ( select 項目名 from ..... )
where 項目名 < ( select 項目名 from ..... )
where 項目名 > ( select 項目名 from ..... )
・・・・・
といった形式でのサブ・クエリーが可能です。


次の例は、「国語」という言葉を書名の一部に含む書籍を出版している出版社を検索するものです。


【例1:「国語」という書籍を出版している出版社を検索(サブ・クエリー)】

select distinct publisher from books where id in (select id from books where title like '%国語%');




概念的には、最も内側のselect文から実行が行われます。
この例では「books」テーブルから「国語」という文字列を含む書名の本が選ばれ、その「id」が返されます。
通常select文の出力は、テーブルを形成するのですが、このselectのネスティングでは、まず内側のselectの出力としてリストで解釈されます。
内側のselect文の出力は、条件を満たす「id」のリストを形成して、今度はwhere句の中で「books」テーブル中の「id」と比較されます。


例1で使用した「distinct」は、重複していない出版社のみを出力する働きを持ちます。
「国語」関する本を二冊出版している会社を二度カウントする必要はないからです。


次の例は、三つのテーブルのジョインに対応しています。
selectのネストも三重になっていることに注目してください。


【例2:「国語」という書籍を出版している出版社を検索(サブ・クエリー)】

select publisher from books where title in ( select title from books2 where id in (select id from keywords where keyword like '%国語%'));




あまり意味のないクエリですが、こんなことも出来ますよという感じで覚えておいて下さい。


サブ・クエリーの中で、
where exists ( select ..... )
where not exists ( select ..... )
といった形式が使われることがあります。


この形式では、内側のselectが、行を見つけることに成功すれば、existsは真を返します。
逆に、not exists は、内側のselectが検索に失敗した時に、真を返します。
これまで見てきたサブ・クエリーとは異なって、外側のselectは内側のselectの返す項目の値を使わないので、existsは通常、次のような形式で用いられます。


where exists ( select * from ..... )
where not exists ( select * from ..... )


次の例は、existsを用いた、「国語」という文字を含む書名の書籍を出版した出版社の検索例です。
この例では、内側のselect文がテーブルとしては「books2」テーブルしか指定していないのに、「books.id」という形で、外側のselect文の「books」テーブルの修飾を受けていることに注目してください。


【例3:「国語」という書籍を出版している出版社を検索(サブ・クエリー)】

select distinct publisher from books where exists ( select * from books2 where title like '%国語%'and id = books.id);






「not exists」を使用した例も書いておきます。


【例4:「国語」という書籍を出版していない出版社を検索(サブ・クエリー)】

select distinct publisher from books where not exists ( select * from books2 where title like '%国語%'and id = books.id);






<<前  [TOP]  次>>