副問い合わせの構文を覚える:ORACLE MASTER Bronze SQL基礎I 講座(9)
Oracleデータベースエンジニアとしての実力を証明するORACLE MASTER資格。その入り口であるBronze資格の取得は難しくない。本連載と、同時掲載中の連載「Bronze DBA講座」で合格を目指そう!(参考記事:「Oracle 10g対応のORACLE MASTERとは?」)
前回に引き続き、副問い合わせによって問い合わせ結果をSQL文の条件に使用する方法について学びます。前回「SELECT文中のSELECT文、副問い合わせ」で、副問い合わせの意味、構文の記述について紹介しました。今回は単一行副問い合わせ、複数行副問い合わせの実行方法を学びましょう。
ORACLE MASTER Bronze SQL基礎I 講座 各回のインデックス
第9回 副問い合わせの構文を覚える
理解しておきたいこと
1.確認しておきたい内容
- 単一行副問い合わせの実行
- 複数行副問い合わせの実行
2.単一行副問い合わせ
結果として1行を戻す副問い合わせは「単一行副問い合わせ」と呼ばれます。単一行副問い合わせでは、単一行比較演算子(=、<、<=、>、>=、!=)を使用することができます。
副問い合わせがNULLを戻す場合、主問い合わせの結果は1行も戻されません。この場合「WHERE列 = NULL」を指定したことになりますが、NULL値は「=」では比較できないためです。
問題
■問題1
次の資料を確認してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
【CUSTOMERS】
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
次の文の結果として正しいものを選択しなさい。
SELECT ord_id, cust_id, ord_date FROM orders
WHERE cust_id = (SELECT cust_id FROM customers WHERE cust_name='SMITH');
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
正解:d
■解説
前回の宿題とした問題です。副問い合わせとの比較演算子に「=」を使用する場合、副問い合わせが1行を戻す必要があります。資料であるCUSTOMERS表には、副問い合わせで使用しているCUST_NAME列が「SMITH」のレコードが2行ありますので、実行時にエラーとなります(正解d)。
選択肢aの結果は、「IN」演算子を使用すれば出力できます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
選択肢bと選択肢cの結果を出力するには、条件が必要ですね。1つの方法として、副問い合わせ内でグループ関数を使用するというものがあります。
■選択肢b:
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
■選択肢c:
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
3.複数行副問い合わせ
結果として複数行を戻す副問い合わせは「複数行副問い合わせ」と呼ばれます。複数行副問い合わせでは、複数行比較演算子(IN、ANY、ALL)を使用します。
IN | 副問い合わせの結果行のいずれかと等しい |
---|---|
ANY | 副問い合わせの結果行のいずれかと比較する(演算子 ANY(副問い合わせ)) |
ALL | 副問い合わせの結果行のすべてと比較する(演算子 ALL(副問い合わせ)) |
いずれかの値と比較するという意味ではINとANYは同じですが、INは=で比較するのに対し、ANYは指定した演算子で、つまり範囲で比較することもできる点が異なります。
問題
■問題1
次の資料を確認してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
次の文の結果として正しいものを選択しなさい。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
正解:d
■解説
この問題のように副問い合わせが入れ子になっている場合は、一番内側の副問い合わせから考えていきましょう。
問い合わせ1 WHERE(問い合わせ2 WHERE(問い合わせ3))
問い合わせ3の結果を使用して問い合わせ2を行い、その結果を問い合わせ1の条件に使用します。
(1)問い合わせ3
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
この結果、CUST_IDが100、102、105の値が戻ります。
(2)問い合わせ2
問い合わせ3の結果を使うと、次のようになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
この結果、ORDER_TOTALが7500、8000、6000の値が戻ります。
(3)問い合わせ1
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ANY演算子は、問い合わせ2の結果のいずれかとの比較をします。7500、8000、6000のいずれかの値より大きなORDER_TOTAL列値を持つ行を求めるので、「ORDER_TOTAL列が6000より大きいORDERS表の行」が答えとなります。演算子として「>」を使用していますので、6000と等しい値は含まれません。正解はdです。
4.トップN分析
FROM句に副問い合わせを使用し、副問い合わせ内でORDER BY句を使用すると、ソート済み結果の集合を作成することができます。主問い合わせ側でROWNUM疑似列を使用し、取得したい行を限定すれば、上位N個のデータを戻すことができます。
SELECT 列名リスト FROM (SELECT 列名リスト FROM 表名 [WHERE 条件式] ORDER BY ソート列)
WHERE ROWNUM <= 取得行数;
・ORDER BY:トップNとして取得する基準を指定する。下位N個を取得するならASCソート、上位N個を取得するならDESCソートを使用する
・ROWNUM:結果の集合に連番を振る疑似的な列。<、<=を使用して取得行数を記述する
ROWNUM疑似列は、現在の表内の格納順序どおりに行に連番を振ってしまいます。上位N個、下位N個を取得するには副問い合わせでソートしておくことが必要です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
5.集合演算子
リレーショナルデータベースでは、数学の集合論を使用して必要な行を戻すことが可能です。Oracleデータベースでは、UNION、INTERSECT、MINUS集合演算子を使用して集合を決定します。
UNION | 各問い合わせで選択されたすべての行を戻す |
---|---|
INTERSECT | 両方の問い合わせで選択された行を戻す |
MINUS | 1つ目の問い合わせで選択された行から、2つ目の問い合わせで選択された行を除く |
いずれの集合演算子も重複値を排除した結果を戻します。UNION ALLという集合演算子だけは例外で、重複値もそのまま戻します。
図1の2つの○が異なる問い合わせと考えましょう。左側の集合にはA、A、B、Cの4つの値が、右側の集合にはA、C、D、Eの4つの値が格納されています。重なっているのは、両方の集合に存在している値です。集合演算子はそれぞれ次の値を戻します。
- UNION:A、B、C、D、E
- UNION ALL:A、A、B、C、A、C、D、E
- INTERSECT:A、C
- MINUS:B
まとめ
前回と今回の2回にわたって、副問い合わせによって問い合わせ結果をSQL文の条件に使用する方法を解説しました。次の内容をチェックしておきましょう。
- 副問い合わせは、ほかの問い合わせ結果に基づく問い合わせ
- 単一行比較演算子(=、、>=、!=)を使用した場合、1行と比較できる。複数行戻るとエラー
- 複数行比較演算子(IN、ANY、ALL)を使用すれば複数行と比較できる
宿題
次回は、「データ操作」を確認します。次の宿題を解いておいてください。
トランザクションを完了する文を2つ選択しなさい。
a.DELETE FROM emp;
b.ROLLBACK TO SAVEPOINT a;
c.GRANT SELECT ON emp TO hr;
d.ALTER TABLE emp ADD COLUMN jobs VARCHAR2(10);
e.SELECT empno, ename FROM emp ORDER BY sal;
Copyright © ITmedia, Inc. All Rights Reserved.