連載
» 2005年12月09日 00時00分 公開

ORACLE MASTER Bronze SQL基礎I 講座(8):SELECT文中のSELECT文、副問い合わせ

Oracleデータベースエンジニアとしての実力を証明するORACLE MASTER資格。その入り口であるBronze資格の取得は難しくない。本連載と、同時掲載中の連載「Bronze DBA講座」で合格を目指そう!(参考記事:「Oracle 10g対応のORACLE MASTERとは?」)

[有限会社 G.F.インフィニティ,Project - ∞]

 本連載第6回「SQLで複数の表からデータを取り出す」、第7回「SQLの外部結合でデータを取り出す」で、複数の表からデータを表示する方法を紹介しました。今回から2回にわたり、副問い合わせによって問い合わせ結果をSQL文の条件に使用する方法について学びましょう。

理解しておきたいこと

1.確認しておきたい内容

  • 副問い合わせのガイドライン
  • 副問い合わせの構文の記述

2.副問い合わせの位置付け

 SELECT文では、WHERE句を使用して行を選択するための条件式が記述できます。これまでに学んだのは値そのものや式を使用した条件でしたが、副問い合わせを使用することで、ほかの問い合わせの結果を条件に使用することができます。いい換えれば副問い合わせとは、SELECT文の中に埋め込まれたSELECT文です。

 例えば「指定した従業員の給与と同額の給与を受け取っている従業員を表示する」場合、まずは従業員の給与を問い合わせ、その給与を条件式に使用する必要があります。副問い合わせを使用すれば、この操作が一度にできます。

図1 副問い合わせ 図1 副問い合わせ

 FROM句で表を指定するのではなく、問い合わせ結果を表に見立てて問い合わせを行う場合も、副問い合わせを使用します。

問題

■問題1

副問い合わせを使用することで__ができるようになる。

上記の__に入る文章を選択しなさい。

a.ほかの問い合わせ結果に基づく問い合わせ
b.NULL値を含む問い合わせ
c.結合する値がなくても結合
d.主キーと外部キーの関係を持つ値の問い合わせ

正解:a

■解説

 副問い合わせは、ほかの問い合わせ結果に基づく問い合わせを実行できる文であり(正解a)、別のSELECT文の句に埋め込まれたSELECT文です。通常WHERE句、HAVING句、FROM句などで使用されます。

 そのほかの選択肢の不正解の理由は次のとおりです。

選択肢b:NULL値を含んでいても結合できるのは、外部結合の特徴です。

選択肢c:結合する値がなくても結合できるのは、外部結合の特徴です。

選択肢d:主キーと外部キーで結合を行うのは、内部結合の特徴です。

■問題2

1つのSELECT文で結果を表示するため、副問い合わせまたは結合を使用する必要があるタスクを2つ選択しなさい。

a.従業員の名前とその上司の名前を同時に表示する
b.給与が2000ドル以上で部門20に属している従業員を表示する
c.指定した従業員の給与と同じ給与を受け取っている従業員を表示する
d.入社してから3カ月以上経過した従業員を表示する
e.歩合給をもらっていない従業員を表示する

正解:a、c

■解説

 前回の宿題とした問題です。副問い合わせは、表そのものに含まれるデータを条件に使用したい場合などに使用します。結合は、複数の表をリンクさせるだけでなく、1つの表を2つの表に見立てて問い合わせを行うときにも使用します。

 正解となる選択肢のタスクは、次のような文で取得できます。

○正解a:従業員の名前とその上司の名前を同時に表示する

SELECT e.ename worker_name, m.ename manager_name
FROM emp e JOIN emp m
ON (e.mgr = m.empno);

○正解c:指定した従業員の給与と同額の給与を受け取っている従業員を表示する

SELECT ename FROM emp
WHERE sal = (SELECT sal FROM emp WHERE empno = 7900);

 そのほかの選択肢の不正解の理由は次のとおりです。

選択肢b:給与が2000ドル以上で部門20に属している従業員を表示する

 副問い合わせや結合を使わずに取得できます。

SELECT ename FROM emp
WHERE sal >= 2000
AND deptno = 20;

選択肢d:入社してから3カ月以上経過した従業員を表示する

 3カ月前の日付より前に入社した従業員を求めればよいわけですから、副問い合わせや結合を使わずに取得できます。

SELECT ename FROM emp
WHERE hiredate < ADD_MONTHS(SYSDATE, -3);

選択肢e:歩合給をもらっていない従業員を表示する

 歩合給をもらっていないということは、歩合給がNULL値と考えられるので、WHERE句で条件を指定するだけです。

SELECT ename FROM emp
WHERE comm IS NULL;

■問題3

副問い合わせに関する説明として正しいものを選択しなさい。

a.副問い合わせでは1行のみ戻すことができる
b.副問い合わせでは0個以上の行を戻すことができる
c.問い合わせ結果に基づいて新規に表の作成ができる
d.NOT NULL列の問い合わせができる
e.主キーと外部キーの関係のある場合にのみ副問い合わせが使用できる

正解:b、c

■解説

 副問い合わせは、別のSELECT文の句に埋め込まれたSELECT文であり、通常はWHERE句、HAVING句、FROM句などで使用されます。

 副問い合わせが1行のレコードを戻すか複数行のレコードを戻すかによって、使用できる比較演算子が変わりますが、副問い合わせでは0レコード以上を戻すことができるといえます(正解b)。また、CREATE TABLE ... AS SELECT構文を使用すれば、副問い合わせの結果を使用した新しい表の作成も可能です(正解c)。

 そのほかの選択肢の不正解の理由は次のとおりです。

選択肢a:副問い合わせでは、複数行を戻す場合も、0レコードを戻す場合もあります。

選択肢d:副問い合わせの実行は、NOT NULL制約がある列でもない列でも可能です。

選択肢e:副問い合わせの実行は、主キーと外部キーという関係がなくても可能です。

3.副問い合わせのタイプ

 WHERE句の条件としてのWHERE句は、次のように使用できます。

SELECT 列名リスト FROM 表名
WHERE 式 演算子 (SELECT 列名 FROM 表名 [WHERE 条件式]);

 式とは、副問い合わせ結果と比較する列または式の値です。

 演算子として、単一行を戻す副問い合わせの場合は「=、<、<=、>、>=、!=」を、複数行を戻す副問い合わせの場合は「IN、ANY、ALL」を使用します。

 副問い合わせは、かっこ内に記述された問い合わせです。

 結果として1行を戻す副問い合わせは「単一行副問い合わせ」、複数行を戻す副問い合わせは「複数行副問い合わせ」と呼ばれます。複数行副問い合わせ(結果として複数行が戻される場合)に単一行副問い合わせの演算子(=、<、<=、>、>=、!=)を使用するとエラーになりますので注意しましょう。

例:
SQL> SELECT empno, ename, sal FROM emp
  2  WHERE  sal = (SELECT sal FROM emp WHERE ename = 'SCOTT');
      
     EMPNO ENAME             SAL
---------- ---------- ---------- 
      7788 SCOTT            3000
      7902 FORD             3000

 副問い合わせでは、グループ関数による結果との比較や、HAVING句を使用した比較も可能です。

問題

■問題1

副問い合わせに関する説明として正しいものを2つ選択しなさい。

a.単一行副問い合わせでは、1列のみ戻すことができる
b.単一行副問い合わせでは、複数列を戻すことができる
c.複数行副問い合わせでは、「=」を使用することができる
d.複数行副問い合わせでは、「>」を使用することができる
e.単一行副問い合わせでは、「IN」を使用することができる

正解:b、e

■解説

 副問い合わせが結果として1行を戻すときは、WHERE句の比較条件は単一行比較演算子を使用します。単一行比較演算子は、=、<、<=、>、>=、!=(<>、^=を含む)です。

 複数行を戻す副問い合わせの場合は、複数行比較演算子(IN、ANY、ALL)を使用する必要があります。

 ここで注意したいことは、単一行比較演算子を使用している場合に複数行が戻されるとエラーになりますが、複数行比較演算子を使用している場合に単一行が戻されてもエラーにはならないということです。そのため、この問題の「単一行副問い合わせでは、『IN』を使用することができる」は、エラーにはならないという点で正解となります(正解e)。

 副問い合わせでは、1列も複数列も戻すことができます(正解b)。

 そのほかの選択肢の不正解の理由は次のとおりです。

選択肢a:副問い合わせでは、1列を戻すことも複数列を戻すことも可能です。

選択肢c:複数行を戻す副問い合わせでは、「=」での比較はできません。単一行比較演算子を使用している場合に複数行が戻されるとエラーとなります。

選択肢d:複数行を戻す副問い合わせでは、「>」での比較はできません。単一行比較演算子を使用している場合に複数行が戻されるとエラーとなります。

宿題

 次回は、今回に引き続き副問い合わせによって問い合わせ結果をSQL文の条件に使用する方法を確認します。次の宿題を解いておいてください。

次の資料を確認してください。

【ORDERS】
ORD_ID CUST_ID ORD_DATE ORDER_TOTAL
------ ------- -------- -----------
   100     100 00-10-17        7500
   101     102 01-05-11        8000
   102     104 02-09-17       12000
   103     103 01-10-21        4500
   104     105 00-06-25        6000
   105     100 02-06-19        5500

【CUSTOMERS】
CUST_ID CUST_NAME
------- ----------
    100 SMITH
    101 ALLEN
    102 WARD
    103 JONES
    104 SMITH

次の文の結果として正しいものを選択しなさい。

SELECT ord_id, cust_id, ord_date FROM orders
WHERE cust_id = (SELECT cust_id FROM customers WHERE cust_name='SMITH');


    a.
          ORD_ID    CUST_ID ORD_DATE
      ---------- ---------- --------
             105        100 02-06-19
             100        100 00-10-17
             102        104 02-09-17
	  
    b.
          ORD_ID    CUST_ID ORD_DATE
      ---------- ---------- --------
             105        100 02-06-19
             100        100 00-10-17
	  			
    c.
          ORD_ID    CUST_ID ORD_DATE
      ---------- ---------- --------
             102        104 02-09-17
			
    d.エラーとなる

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。