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

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

HSQLDBを使用したデータベース入門その4 selectのネスティング(2020年5月更新)

<<前  [TOP]  次>>


テーブルのジョインを行うにはもう一つの方法があります。
それはselect文の内部で再び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 distinct publisher from books where id in (select id from books where title like &#x27;%国語%&#x27;);」
「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 '%国語%'));



「select publisher from books where title in ( select title from books2 where id in (select id from keywords where keyword like &#x27;%国語%&#x27;));」
「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);



「select distinct publisher from books where exists ( select * from books2 where title like &#x27;%国語%&#x27;and id = books.id);」
「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);



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


<<前  [TOP]  次>>